Spring AOP源码(三):创建AOP相关的Bean
在Spring AOP源码(二):BeanDefinition的准备工作中,介绍了Spring准备AOP相关的BeanDefinition对象,同样的对于普通的bean对象的创建此处不再赘述,主要分析动态代理创建器、Advisor是如何实例化的。
1、动态代理模式创建器实例化
在上一篇中已经知道Spring中AOP的自动代理模式创建器AnnotationAwareAspectJAutoProxyCreator。
AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,同时也实现了Ordered接口。
PostProcessorRegistrationDelegate#registerBeanPostProcessors核心伪代码如下:
1 // 注册并实例化AOP的动态代理 2 public static void registerBeanPostProcessors( 3 ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 4 5 // 找到所有实现了BeanPostProcessor接口的类 6 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); 7 // ...... 8 // 定义存放实现了Ordered接口的BeanPostProcessor的name集合 9 List<String> orderedPostProcessorNames = new ArrayList<>(); 10 // ...... 11 // 注册所有实现Ordered的beanPostProcessor 12 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); 13 for (String ppName : orderedPostProcessorNames) { 14 // 根据ppName找到对应的BeanPostProcessor实例对象 15 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 16 // 将实现了Ordered接口的BeanPostProcessor添加到orderedPostProcessors集合中 17 orderedPostProcessors.add(pp); 18 } 19 // 注册实现了Ordered接口的BeanPostProcessor实例添加到beanFactory中 20 registerBeanPostProcessors(beanFactory, orderedPostProcessors); 21 // ...... 22 }
有一点需要注意,AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,这个在将BeanPostProcessor注册到beanPostProcessors容器中时,会将AbstractBeanFactory属性hasInstantiationAwareBeanPostProcessors实例化后置处理器注册标识设置为true。
AbstractBeanFactory#addBeanPostProcessor核心伪代码如下:
1 // 将BeanPostProcessor注册到beanPostProcessors容器中 2 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { 3 4 // 如果beanPostProcessors集合中已经存在此beanPostProcessors对象,移除该对象 5 this.beanPostProcessors.remove(beanPostProcessor); 6 7 // beanPostProcessor是为InstantiationAwareBeanPostProcessor类型,Bean对象实例化后置处理器注册标识设置为true 8 if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { 9 this.hasInstantiationAwareBeanPostProcessors = true; 10 } 11 12 // 将beanPostProcessor加入后置处理器集合中 13 this.beanPostProcessors.add(beanPostProcessor); 14 }
hasInstantiationAwareBeanPostProcessors标识在后续的Advisor实例化中会用到,这里先记住这个结论。
2、Advisor的实例化
2.1、AOP常用五大通知Advice的类图
1、前置通知 AspectJMethodBeforeAdvice
2、后置通知 AspectJAfterAdvice
3、环绕通知 AspectJAroundAdvice
4、后置返回通知 AspectJAfterReturningAdvice
5、后置异常通知 AspectAfterThrowingAdvice
6、结论
2.2、Advisor的实例化
1、Advisor实例化的时机
有个问题需要我们思考,Advisior是在哪个步骤做实例化的呢,我们先看下Bean的生命周期:
2、Advisor创建的核心流程
由此上面的流程可知,在aop切面aspect的普通bean标签的实例化时,在实例化之前,查找beanFactory容器中所有实现Advisor的beanDefinition并做实例化操作,并将遍历Advisor集合,如果Advisor集合中的存在某个Advisor切面的AspectName与正在创建的beanName相同,则跳过resolveBeforeInstantiation处理。
1 // 是否应该跳过 2 protected boolean shouldSkip(Class<?> beanClass, String beanName) { 3 // 查找并创建容器中所以的Advisor 4 List<Advisor> candidateAdvisors = findCandidateAdvisors(); 5 // 遍历Advisor集合 6 for (Advisor advisor : candidateAdvisors) { 7 // Advisor是AspectJPointcutAdvisor类型并且Advisor中的切面与正在创建的beanName相同 8 if (advisor instanceof AspectJPointcutAdvisor && 9 ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { 10 return true; 11 } 12 } 13 return super.shouldSkip(beanClass, beanName); 14 }
AbstractAdvisorAutoProxyCreator#findAdvisorBeans 查找并实例化Advisor的核心伪代码:
1 // 查找容器中所有的Advisor对象 2 public List<Advisor> findAdvisorBeans() { 3 // 获取已经缓存的Advisor的beanName集合 4 String[] advisorNames = this.cachedAdvisorBeanNames; 5 6 if (advisorNames == null) { 7 // 获取当前BeanFactory中所有实现了Advisor接口的bean的名称 8 advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( 9 this.beanFactory, Advisor.class, true, false); 10 this.cachedAdvisorBeanNames = advisorNames; 11 } 12 13 if (advisorNames.length == 0) { 14 return new ArrayList<>(); 15 } 16 17 // 对获取到的实现Advisor接口的bean的名称进行遍历 18 List<Advisor> advisors = new ArrayList<>(); 19 // 循环所有的beanName,找出对应的增强方法 20 for (String name : advisorNames) { 21 // 创建Advisor, 并将当前bean添加到Advisor集合中,用于后续遍历 22 advisors.add(this.beanFactory.getBean(name, Advisor.class)); 23 } 24 return advisors; 25 }
getBean -> doGetBean -> CreateBean -> doCreateBean,此处便是创建Advisor的bean的地方。
3、Advisor实例化步骤
3.1、Advisor的有参构造函数
1 // 为给定的Advice创建一个AspectJPointcutAdvisor实例 2 public AspectJPointcutAdvisor(AbstractAspectJAdvice advice) { 3 Assert.notNull(advice, "Advice must not be null"); 4 this.advice = advice; 5 this.pointcut = advice.buildSafePointcut(); 6 }
3.2、Advice的有参构造函数
1 public AspectJAfterAdvice( 2 Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 4 super(aspectJBeforeAdviceMethod, pointcut, aif); 5 }
1 public AspectJMethodBeforeAdvice( 2 Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 4 super(aspectJBeforeAdviceMethod, pointcut, aif); 5 }
AspectJAroundAdvice - 环绕通知的有参构造函数
1 public AspectJAroundAdvice( 2 Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 4 super(aspectJAroundAdviceMethod, pointcut, aif); 5 }
AspectJAfterReturningAdvice - 后置返回通知的有参构造函数
1 public AspectJAfterReturningAdvice( 2 Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 4 super(aspectJBeforeAdviceMethod, pointcut, aif); 5 }
AspectJAfterThrowingAdvice - 后置异常通知有参构造函数
1 public AspectJAfterThrowingAdvice( 2 Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 4 super(aspectJBeforeAdviceMethod, pointcut, aif); 5 }
advisor的有参构造函数中,参数为Advice; Advice的有参构造函数中,参数为Method、AspectJExpressionPointcut、AspectInstanceFactory。要想实例化Advisor,必须先实例化Advice; 若要实例化Advice,必须先实例化Method、AspectJExpressionPointcut、AspectInstanceFactory,这个实例化过程是很麻烦的。
3.3、Advice有参构造函数中的参数实例
Advisor实例化的核心流程: