这次来浅谈一下注解spring AOP 的源码,在spring底层代码中,作为开启注解AOP的 @EnableAspectJAutoProxy 究竟干了些啥。 本文章记录的是博主学习aop源码的一些理解,如果有错,望指出
它,长这样: 这里重点是 @Import(AspectJAutoProxyRegistrar.class),导入了 AspectJAutoProxyRegistrar.class。
进入这个类中,在注释中发现这个类是用来将 AnnotationAwareAspectJAutoProxyCreator 这个类注册到 BeanDefinitionRegistry 里。 AnnotationAwareAspectJAutoProxyCreator 这个类是什么呢?这里先不说,在后面更新的文章中会详细讲解。
那么,这个类要怎么把 AnnotationAwareAspectJAutoProxyCreator 这个类注册到 BeanDefinitionRegistry 里的呢?
继续往下看,可以看到该类中重写了一个方法: 这里关注一下圈起来的代码,这个代码的意思大概是“如果需要的话就注册AspectJAnnotationAutoProxy的创造者”。点进去之后会发现方法内又调用了与该方法重名的另一个方法: 圈起来的代码的大意是“注册或升级xxx(我也不懂)”,然后传入了上面提到的 AnnotationAwareAspectJAutoProxyCreator.class,此时继续进去看看发生了什么。
@Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); /** 直接看这里 这里是判断bean的定义工厂registry中有没有 AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator" 第一次运行项目时是没有的,结果为 false */ if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } /** 此时代码执行到这里; 下方的代码都是在向bean定义工厂中注册 AnnotationAwareAspectJAutoProxyCreator,并且该类的名称设置为 org.springframework.aop.config.internalAutoProxyCreator, 由此:internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreato */ RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }代码执行完之后,registry 中已经存在了 AnnotationAwareAspectJAutoProxyCreator 的定义。
注意:这时,AnnotationAwareAspectJAutoProxyCreator 只是在bean工厂中定义了,还没有创建对象。 到此,@EnableAspectJAutoProxy 做了一件事,将 AnnotationAwareAspectJAutoProxyCreator 定义到了bean的工厂中(尚未创建对象)
在这些类中需要关注 3 个方法: AbstractAutoProxyCreato.postProcessAfterInitializationj() AbstractAutoProxyCreato.postProcessBeforeInstantiation() AbstractAdvisorAutoProxyCreator.setBeanFactory()
这三个方法可以让我们在理解AOP代码的过程中起到很大的作用。
先定义一个增强类和被增强类并注入到IOC容器中,并打上断点
/** * 告诉spring这个类是切面类(增强类) */ @Aspect public class LogAspect { /** 抽取切入点表达式 * */ @Pointcut("execution(* aopEntity.PlayGame.*(..))") public void pointcut(){} /** * 前置通知 */ @Before(value = "pointcut()") public void logStart(){ System.out.println("前置通知执行。。。"); } @After(value = "pointcut()") public void logAfter(){ System.out.println("后置通知执行。。。"); } @AfterReturning(value="pointcut()") public void logReturning(){ System.out.println("返回通知执行。。。"); } @AfterThrowing(value = "pointcut()") public void logThrowing(){ System.out.println("异常通知执行。。。"); } } /** 被增强类 */ public class PlayGame { public void play(){ System.out.println("开始play。。。"); } } /** * 开启基于注解的aop功能 */ @EnableAspectJAutoProxy @Configuration public class AopConfig { /** * 将业务逻辑类加载到容器中 * 打上断点 * @return */ @Bean public PlayGame playGame(){ return new PlayGame(); } /** * 将切面类加载到容器中 * 打上断点 */ @Bean public LogAspect logAspect(){ return new LogAspect(); } }步骤: 1、传入配置类,调用 refresh() 刷新容器 2、 调用 registerBeanPostProcessors(beanFactory) :注册拦截Bean创建的Bean处理器 3、 调用PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); 4、 获取所有已经定义了需要获取对象的所有BeanPostProcessor
5、 分别给容器中添加实现了PriorityOrdered接口、Ordered接口、没实现以上接口的BeanPostProcessor 6、 注册实现Ordered接口的internalAutoProxyCreator(实际上就是AnnotationAwareAspectJAutoProxyCreator) ,。AnnotationAwareAspectJAutoProxyCreator 已经实现了Ordered 接口 getBean()调用流程:getBean()->doGetBean()->getSingleton() 6.1 、先给Bean赋值(populateBean()方法),然后创建并初始化bean实例 6.2、 执行Aware接口中的被实现的setBeanFactory() 6.3、 执行applyBeanPostProcessorsBeforeInitialization()。获取所有的后置处理器,调用每个后置处理器中的postProcessBeforeInitialization()
6.4、 执行自定义的初始化方法 6.5、 执行applyBeanPostProcessorsAfterInitialization。获取所有的后置处理器,调用每个后置处理器中的postProcessAfterInitialization() 7、 完成internalAutoProxyCreator(实际上就是AnnotationAwareAspectJAutoProxyCreator) 的初始化操作
8、 初始化BeanFactory,到此,AnnotationAwareAspectJAutoProxyCreator 创建成功。 8、 添加到已创建的bean的集合中。
9、 对beanPostProcessors进行排序和注册
到此,**AnnotationAwareAspectJAutoProxyCreator **创建注册完成。
粗浅分析注解spring AOP源码--------(二)