配置
1.引入aop jar包
2.在主类上面加@EnableAspectJAutoProxy
这里要说一句:市面上常用有两种aop实现方式第一种是springaop,第二种是AspectJ,但是原始springaop的语法非常复杂,而AspectJ语法非常简单所有后来spring借用其语法方式,使用@EnableAspectJAutoProxy就是开启AspectJ编码方式,而不直接用AspectJ是因为:
1.Spring的AOP是基于动态代理的,动态增强目标对象,而AspectJ是静态编译时增强,需要使用自己的编译器来编译,还需要织入器.
2.使用AspectJ编写的java代码无法直接使用javac编译,必须使用AspectJ增强的ajc增强编译器才可以通过编译,写法不符合原生Java的语法;而Spring AOP是符合Java语法的,也不需要指定编译器去编译,一切都由Spring 处理.
3.这样就可以开始使用写切面类了
/**
* 首先,这个@Aspect注释告诉Spring这是个切面类
* @Compoment将转换成Spring容器中的bean或者是代理bean,其实就是告诉spring这是配置类,不用xml
* 总之要写切面这两个注解一起用就是了。
* 既然是切面类,那么肯定是包含PointCut还有Advice两个要素的,
*下面对几个注解展开讲来看看在@Aspect中是怎么确定切入点(PointCut)和增强通知(Advice)的。*/
@Aspect
@Component
public class WebLogAspect {
private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
//切入点描述 这个是controller包的切入点 不用写方法这里只高所连接点是什么
@Pointcut("execution(public * com.yuanpeng.controller..*.*(..))")
public void controllerLog(){}
/**
@Pointcut 这个就是连接点集合,上面写的就是所有controller下的类的所有方法
@Pointcut后面的表达式是这里最难的
https://www.jianshu.com/p/fbbdebf200c9 这里有详细解释
*/
@Before("controllerLog()") //在切入点的方法run之前要干的
/**
这里就是Advice加入方法时机,这种方法统称叫通知,在这里选上面的@Pointcut
方法名,然后写你要的方法就好了
@Before:在切点方法前执行
@After:在切点方法后执行
@Around:在切点方法外环绕执行 多用于事物吧
@AfterThrowing: 在异常抛出前进行处理,比如记录错误日志
@AfterRetruning: 在方法返回之前,获取返回值并进行记录操作
**/
public void logBeforeController(JoinPoint joinPoint) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
// 记录下请求内容
logger.info("################URL : " + request.getRequestURL().toString());
logger.info("################HTTP_METHOD : " + request.getMethod());
logger.info("################IP : " + request.getRemoteAddr());
logger.info("################THE ARGS OF THE CONTROLLER : " + Arrays.toString(joinPoint.getArgs()));
//下面这个getSignature().getDeclaringTypeName()是获取包+类名的 然后后面的joinPoint.getSignature.getName()获取了方法名
logger.info("################CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
logger.info("################TARGET: " + joinPoint.getTarget());//返回的是需要加强的目标类的对象
logger.info("################THIS: " + joinPoint.getThis());//返回的是经过加强后的代理类的对象
}
}