简介
切面编程,提取与业务无关的操作,实现一些方法增强、日志、事务、权限等功能。原理:JDK动态代理或者CGLib代理
实现
- 解析aspectj-autoproxy,注册AnnotationAwareAspectJAutoProxyCreater,该类间接实现了beanPostProcessor接口,实例化bean的时候,会调用applyBeanPostProcessorsBeforeInitialization、applyBeanPostProcessorsAfterInitialization两个方法
- 创建增强,通过applyBeanPostProcessorsBeforeInitialization完成
- 首先根据配置的增强信息,通过findCandidateAdvisor方法查找增强信息
- 其次,通过buildAspectJAdvisor方法创建增强,其实现过程主要依赖AdvisorFactory来完成。找到配置的@AspectJ切面,提取注解元数据并创建增强
- 创建代理,通过applyBeanPostProcessorsAfterInitialization方法完成
- 入口方法为warpIfNecessary方法
- 调用getAdvicesAndAdvisorsForBean方法查找适合当前bean的增强,具体过程为先从上一步结果中得到所有增强,然后调用findAdvisorsThatCanApply方法,根据切点表达式,判断当前bean是否应该被代理
- 如果当前bean应该被代理,则通过ProxyFactory创建代理,在创建代理的过程中需要判断使用JDK动态代理或者CGLib动态代理
- isOptimize(),判断是否使用了优化策略
- proxy_target_class,判断是否强制开启了CGLib动态代理
- 是否存在代理接口
- 以上三种情况,需要使用CGLib动态代理
- 调用,假设当前使用的是JDK的动态代理
- 调用getInterceptorsAndDynamicInterceptionAdvice方法获取所有拦截器,形成一个List拦截器链
- 创建MethodInvocation对象,并将上一步获取到的拦截器链封装至此MethodInvocation中
- 以递归的形式调动proceed方法,并通过currentIndex下标判断终止条件,当条件满足后,通过invokeJoinPoint方法调用具体的业务方法
- 这里较为特殊的是环绕增强,环绕增强需要接受一个JoinPoint参数,开发人员需要手动调用proceed方法,以实现环绕增强