自定义一个注解,稍后aop配置只有加了这个注解的才能被aop扫描到,就是当操作了有自定义注解的方法才会记录到系统日志。
package aop;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String title() default "";
String description() default "";
}
重点就是切面这个类,正常前置通知,后置返回通知什么的可以获取方法参数,返回值什么的。但是这个是根据有注解才进行切面的,所以也可以获取注解中相应的信息,所以自定义注解要设计好。下面的切面代码是随便写写,真正使用的时候,根据自己的需求修改下就行了。
package aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
@Component
@Aspect
public class HelloAspectJ {
public HelloAspectJ(){
System.out.println("HelloAspectJ扫描到了");
}
@Pointcut(value = "@annotation(aop.SystemControllerLog)")
public void beforePointcut() {
}
// 前置通知
@Before(value = "beforePointcut()")
public void beforeHello(JoinPoint joinPoint) throws ClassNotFoundException {
System.out.println("===========hello beforeHello(前置通知)==" );
Object obj[] = joinPoint.getArgs();
for (Object o : obj) {
System.out.println("目标方法参数值:"+o.toString());
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
String targetName = joinPoint.getTarget().getClass().getName();
System.out.println("目标方法所在类名称:"+targetName);
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String methodName = joinPoint.getSignature().getName();
System.out.println("目标方法名称:"+methodName);
for (Method method : methods) {
System.out.println("目标方法所在类的方法:"+method.getName());
if(method.getName().equals(methodName)) {
SystemControllerLog annotation = method.getAnnotation(SystemControllerLog.class);
System.out.println("目标方法注解类标题:"+annotation.title());
System.out.println("目标方法注解类描述:"+annotation.description());
Class[] classes = method.getParameterTypes();
for (Class aClass : classes) {
System.out.println("目标方法参数类型:"+aClass.toString());
}
}
}
}
// 后置返回通知
@AfterReturning(value = "execution(* controller..*.*(..))")
public void afterReturningHello(JoinPoint joinPoint) {
System.out.println("===========hello afterReturningHello(后置返回通知)==");
}
}
在springmvc.xml配置文件中加入包扫描和使用注解方式进行切面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="controller"/>
<context:component-scan base-package="aop"/>
<aop:aspectj-autoproxy/>
...
</beans>
在controller的方法里加入注解就可以被aop拦截到了,然后就可以在切面的代码里写自己想要的东西了。
package controller;
import aop.SystemControllerLog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloWorldController {
public HelloWorldController() {
System.out.println("HelloWorldController扫描到了!!!");
}
@RequestMapping("aopTest")
@SystemControllerLog(title = "hello",description="aopTest")
public String aopTest(Integer id,String name){
System.out.println("id:"+id);
System.out.println("name:"+name);
return "hello";
}
}