AOP源码解析:AspectJAwareAdvisorAutoProxyCreator类的介绍

AspectJAwareAdvisorAutoProxyCreator 的类图

上图中一些 类/接口 的介绍:html

AspectJAwareAdvisorAutoProxyCreator : 公开了AspectJ的调用上下文,并弄清楚来自同一切面的多个Advisor在AspectJ中的优先级规则。java

AbstractAdvisorAutoProxyCreator : 通用自动代理建立器,它基于检测到的每一个顾问程序为特定bean构建AOP代理。git

AbstractAutoProxyCreator扩展了 ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 实现,该实现使用AOP代理包装每一个合格的bean,并在调用bean自己以前委派给指定的拦截器。github

BeanFactoryAware : 实现了该接口的Bean能够知道它属于那个 BeanFactory,Bean能够经过Spring容器查找它的协同者(依赖查找),但大多数的Bean是经过构造器参数和Bean方法(依赖注入)来获取它的协同者。spring

BeanPostProcessor :工厂钩子,容许自定义修改新的bean实例。例如,检查标记接口或使用代理包装bean。若是咱们须要在Spring容器中完成Bean的实例化,配置和其初始化先后添加一些本身的逻辑处理,咱们就能够定义一个或多个BeanPostProcessor接口的实现,而后注册到容器中。缓存

InstantiationAwareBeanPostProcessor :  BeanPostProcessor 的子接口,它添加了实例化以前的回调,以及实例化以后但设置了显式属性或自动装配以前的回调。它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,实现这个接口须要实现5个方法。InstantiationAwareBeanPostProcessor 接口的主要做用在于目标对象的实例化过程当中须要处理的事情,包括实例化对象的先后过程以及实例的属性设置。ide

SmartInstantiationAwareBeanPostProcessorInstantiationAwareBeanPostProcessor 接口的扩展,多出了3个方法,添加了用于预测已处理bean的最终类型的回调,再加上父接口的5个方法,因此实现这个接口须要实现8个方法,主要做用也是在于目标对象的实例化过程当中须要处理的事情。源码分析

AspectJAwareAdvisorAutoProxyCreator为 AspectJ 切面类建立自动代理。post

 

  BeanPostProcessor 接口中的两个方法 postProcessBeforeInitialization 和 postProcessAfterInitialization,做用是对Bean初始化先后添加一些本身的逻辑。ui

1     @Nullable
2     default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
3         return bean;
4     }
5 
6     @Nullable
7     default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
8         return bean;
9     }

  InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,它额外增长了3个新的方法:postProcessBeforeInstantiation( 目标对象被实例化以前调用的方法,能够返回目标实例的一个代理用来代替目标实例 )、postProcessAfterInstantiation(该方法在Bean实例化以后执行,返回false,会忽略属性值的设置;若是返回true,会按照正常流程设置属性值) 和 postProcessPropertyValues(对属性值进行修改,将来版本将会删除)。

 1     @Nullable
 2     default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
 3         return null;
 4     }
 5 
 6     default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
 7         return true;
 8     }
 9 
10     @Nullable
11     default PropertyValues postProcessPropertyValues(
12             PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
13 
14         return pvs;
15     }

  SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,里面定义了3个方法:predictBeanType(预测Bean的类型)、determineCandidateConstructors(选择合适的构造器)、getEarlyBeanReference(解决循环引用问题)。

 1     @Nullable
 2     default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
 3         return null;
 4     }
 5 
 6     @Nullable
 7     default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
 8         return null;
 9     }
10 
11     default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
12         return bean;
13     }

  AbstractAutoProxyCreator 是AOP的一个核心类,它实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,实现了代理建立的逻辑,使用AOP代理包装每一个合格的bean,并在调用bean自己以前委派给指定的拦截器。

  AbstractAdvisorAutoProxyCreator 通用自动代理建立器,它基于检测每一个bean的加强器,为特殊的bean构建AOP代理。子类能够重写此findCandidateAdvisors()方法,以返回适用于任何对象的advisor的自定义列表,子类还能够重写继承的AbstractAutoProxyCreator.shouldSkip()方法,以将某些对象排除在自动代理以外。

1     protected List<Advisor> findCandidateAdvisors() {
2         Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
3         return this.advisorRetrievalHelper.findAdvisorBeans();
4     }

  AspectJAwareAdvisorAutoProxyCreator 扩展 AbstractAdvisorAutoProxyCreator,公开了AspectJ的调用上下文,并在多个加强器来自同一切面时搞清楚AspectJ的建议优先级顺序。按AspectJ优先级排序其他部分:

 1     @Override
 2     @SuppressWarnings("unchecked")
 3     protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
 4         List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
 5         for (Advisor element : advisors) {
 6             partiallyComparableAdvisors.add(
 7                     new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
 8         }
 9         List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
10         if (sorted != null) {
11             List<Advisor> result = new ArrayList<>(advisors.size());
12             for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
13                 result.add(pcAdvisor.getAdvisor());
14             }
15             return result;
16         }
17         else {
18             return super.sortAdvisors(advisors);
19         }
20     }

  在加强链头部增长一个ExposeInvocationInterceptor,使用AspectJ表达式切入点和使用AspectJ样式的advisor时,须要这些附加advisor。

1     protected void extendAdvisors(List<Advisor> candidateAdvisors) {
2         AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
3     }

  若是此后处理器不该该考虑将给定的bean用于自动代理,子类应重写此方法以返回true

 1     @Override
 2     protected boolean shouldSkip(Class<?> beanClass, String beanName) {
 3         // TODO: Consider optimization by caching the list of the aspect names
 4         List<Advisor> candidateAdvisors = findCandidateAdvisors();
 5         for (Advisor advisor : candidateAdvisors) {
 6             if (advisor instanceof AspectJPointcutAdvisor &&
 7                     ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
 8                 return true;
 9             }
10         }
11         return super.shouldSkip(beanClass, beanName);
12     }

  AspectJAwareAdvisorAutoProxyCreator 还有一个子类叫 AnnotationAwareAspectJAutoProxyCreator,子类AnnotationAwareAspectJAutoProxyCreator是用于处理当前应用程序上下文中的全部AspectJ注释方面以及Spring Advisor。若是Spring AOP的基于代理的模型可以应用任何AspectJ注释的类,它们的advisor将被自动识别,这涵盖了方法执行链接点,Spring Advisor的处理遵循AbstractAdvisorAutoProxyCreator中创建的规则。

生成代理对象

  从使用<aop:xxx>标签来自动生成代理的话,先看看AopNamespaceHandler,使用<aop:config>标签则使用 ConfigBeanDefinitionParser 解析,使用了<aop:aspectj-autoproxy>标签则使用 AspectJAutoProxyBeanDefinitionParser 解析,依次类推。

 1     @Override
 2     public void init() {
 3         // In 2.0 XSD as well as in 2.1 XSD.
 4         registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
 5         registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
 6         registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
 7 
 8         // Only in 2.0 XSD: moved to context namespace as of 2.1
 9         registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
10     }
  • <aop:config>方式使用 AspectJAwareAdvisorAutoProxyCreator 建立代理

  • <aop:aspectj-autoproxy>使用 AnnotationAwareAspectJAutoProxyCreator 建立代理

ConfigBeanDefinitionParser.java

 1     @Override
 2     @Nullable
 3     public BeanDefinition parse(Element element, ParserContext parserContext) {
 4         CompositeComponentDefinition compositeDef =
 5                 new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
 6         parserContext.pushContainingComponent(compositeDef);
 7 
 8         configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator
 9 
10         List<Element> childElts = DomUtils.getChildElements(element);
11         for (Element elt: childElts) {
12             String localName = parserContext.getDelegate().getLocalName(elt);
13             if (POINTCUT.equals(localName)) {
14                 parsePointcut(elt, parserContext);
15             }
16             else if (ADVISOR.equals(localName)) {
17                 parseAdvisor(elt, parserContext);
18             }
19             else if (ASPECT.equals(localName)) {
20                 parseAspect(elt, parserContext);
21             }
22         }
23 
24         parserContext.popAndRegisterContainingComponent();
25         return null;
26     }
27 
28     private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
29         AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
30     }

AopConfigUtils.java

1     public static void registerAspectJAutoProxyCreatorIfNecessary(
2             ParserContext parserContext, Element sourceElement) {
3        // 在这里注册的是AspectJAwareAdvisorAutoProxyCreator
4         BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
5                 parserContext.getRegistry(), parserContext.extractSource(sourceElement));
6         useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
7         registerComponentIfNecessary(beanDefinition, parserContext); // 注册组件 8     }
1     @Nullable
2     public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(
3             BeanDefinitionRegistry registry, @Nullable Object source) {
4 
5         return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
6     }

  AspectJAwareAdvisorAutoProxyCreator 实现了 BeanPostProcessor 等上面介绍的接口,主要做用于Bean初始化先后,实例化先后,全部的Bean都被做用到。InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口,但它的调用时间点发生在Bean实例化前,在真正调用doCreateBean()建立bean实例以前执行postProcessBeforeInstantiation()。

AbstractAutoProxyCreator.java

 1     @Override
 2     public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
 3         Object cacheKey = getCacheKey(beanClass, beanName);  // 获得一个缓存的惟一key(根据beanClass和beanName生成惟一key)  4      // 若是当前targetSourcedBeans(经过自定义TargetSourceCreator建立的TargetSource)不包含cacheKey
 5         if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
 6             if (this.advisedBeans.containsKey(cacheKey)) {  //advisedBeans(已经被加强的Bean,即AOP代理对象)中包含当前cacheKey,返回null,即走Spring默认流程  7                 return null;
 8             }
 9             if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 若是是基础设施类(如Advisor、Advice、AopInfrastructureBean的实现)不进行处理;(略) 10                 this.advisedBeans.put(cacheKey, Boolean.FALSE);
11                 return null;
12             }
13         }
14 
15         // 若是有自定义的TargetSource,在此处建立代理
16         // 禁止目标Bean的没必要要的默认实例化:
17         // TargetSource将以自定义方式处理目标实例。
18         TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
19         if (targetSource != null) {
20             if (StringUtils.hasLength(beanName)) {
21                 this.targetSourcedBeans.add(beanName);
22             }
23             Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
24             Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
25             this.proxyTypes.put(cacheKey, proxy.getClass());
26             return proxy;
27         }
28 
29         return null;
30     }

经过 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 建立AOP代理。

 1     @Override
 2     public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
 3         if (bean != null) {
 4             Object cacheKey = getCacheKey(bean.getClass(), beanName);
 5             if (!this.earlyProxyReferences.contains(cacheKey)) {  // 若是以前调用过getEarlyBeanReference获取包装目标对象到AOP代理对象(若是须要),则再也不执行  6                 return wrapIfNecessary(bean, beanName, cacheKey);  // 包装目标对象到AOP代理对象(若是须要)  7             }
 8         }
 9         return bean;
10     }
11     
12     protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
13         if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 经过TargetSourceCreator进行自定义TargetSource不须要包装 14             return bean;
15         }
16         if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {  // 不该该被加强对象不须要包装 17             return bean;
18         }
19         if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基础设施或应该skip的不须要保证 20             this.advisedBeans.put(cacheKey, Boolean.FALSE);
21             return bean;
22         }
23 
24         // 若是有advise则建立代理。
25         Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
26         if (specificInterceptors != DO_NOT_PROXY) {
27             this.advisedBeans.put(cacheKey, Boolean.TRUE);
28             Object proxy = createProxy(
29                     bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 建立代理对象 30             this.proxyTypes.put(cacheKey, proxy.getClass());
31             return proxy;
32         }
33 
34         this.advisedBeans.put(cacheKey, Boolean.FALSE);
35         return bean;
36     }

参考:

Spring内部的BeanPostProcessor接口总结

【Spring源码分析】AOP源码解析(下篇)

相关文章
相关标签/搜索