spring aop源码解析2: AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程

spring aop的源码解析内容比较多,分为三个部分:

1. 创建、初始化并注册AnnotationAwareAspectJAutoProxyCreator

参考:spring aop源码解析1: 创建、初始化并注册AnnotationAwareAspectJAutoProxyCreator

2. AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程

参考:spring aop源码解析2: AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程

3. 代理对象执行过程分析--构造拦截器链及触发拦截器链

参考:spring aop源码解析3: 代理对象执行过程分析--构造拦截器链及触发拦截器链

这一篇为第二篇。

接上一篇spring aop源码解析1: 创建、初始化并注册AnnotationAwareAspectJAutoProxyCreator继续

现在我们在容器中已经有了AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor,那么之后我们再创建bean的时候,都会经过AnnotationAwareAspectJAutoProxyCreator这个后置处理器

接下来看这个后置处理器能干什么

AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor

 

由于流程比较复杂,还是先上一张流程图

 

4.完成其余BeanFactory的初始化工作

在refresh方法中 注册好了BeanPostProcessor之后,执行finishBeanFactoryInitialization方法

org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

// Instantiate all remaining (non-lazy-init) singletons.

finishBeanFactoryInitialization(beanFactory);

初始化剩下的单实例bean

为什么说是剩下的bean呢?比如说我们的一些BeanPostProcessor bean,已经在前面创建、初始化并注册到容器中了

// Instantiate all remaining (non-lazy-init) singletons.

beanFactory.preInstantiateSingletons();

这里的beanFactory是DefaultListenableBeanFactory

 

4.1 遍历获取容器中所有的Bean,依次创建对象getBean(beanName);

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

// Trigger initialization of all non-lazy singleton beans...

for (String beanName : beanNames) {
...

else {

   getBean(beanName);

}

getBean->doGetBean()->getSingleton()->

4.2 创建bean

AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor会在所有bean创建之前会有一个拦截,因为其实现了InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()

4.2.1 先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;

// Eagerly check singleton cache for manually registered singletons.

Object sharedInstance = getSingleton(beanName);

只要创建好的Bean都会被缓存起来,保证单实例Bean只会被创建一次

 

4.2.2 createBean();创建bean;

Central method of this class: creates a bean instance,populates the bean instance, applies post-processors, etc.

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例

BeanPostProcessor后置处理器与InstantiationAwareBeanPostProcessor后置处理器不一样

BeanPostProcessor是在Bean对象创建完成初始化前后调用的

InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象

 

4.2.2.1 resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation

希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续执行doCreateBean

try {

   // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

   if (bean != null) {

      return bean;

   }

}

后置处理器先尝试返回对象;

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

   Class<?> targetType = determineTargetType(beanName, mbd);

   if (targetType != null) {

      bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

      if (bean != null) {

         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

      }

   }

}

先执行applyBeanPostProcessorsBeforeInstantiation

如果不为null,再执行applyBeanPostProcessorsAfterInitialization

 

拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor这种类型

注意,我们第3步创建的AnnotationAwareAspectJAutoProxyCreator就是这种类型的BeanPostProcessor

就执行postProcessBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {

   for (BeanPostProcessor bp : getBeanPostProcessors()) {

      if (bp instanceof InstantiationAwareBeanPostProcessor) {

         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);

         if (result != null) {

            return result;

         }

      }

   }

   return null;

}

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

 

注意看注解:

如果我们有自定义TargetSource,请在此处创建代理。

禁止目标bean的不必要的默认实例化:

TargetSource将以自定义方式处理目标实例。

也就是说当注册了AnnotationAwareAspectJAutoProxyCreator之后,再创建任何一个bean的时候,都要先被其拦截一下,看这个bean是直接由这个BeanPostProcessor生成一个proxy对象后返回,还是走常规的创建过程

 

4.2.2.2 如果不能,

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

真正的去创建一个bean实例;和3.4创建AnnotationAwareAspectJAutoProxyCreator这个bean流程一样;

5. AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程

AnnotationAwareAspectJAutoProxyCreator

其实现了InstantiationAwareBeanPostProcessor

其处理过程

5.1. 每一个bean创建之前,调用postProcessBeforeInstantiation();

关心MathCalculator和LogAspect的创建

5.1.1 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)

if (this.advisedBeans.containsKey(cacheKey)) {

   return null;

}

5.1.2 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)

 

if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {

   this.advisedBeans.put(cacheKey, Boolean.FALSE);

   return null;

}

先执行

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass

return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));

注意在这里判断了是不是@Aspect

 

调用AnnotationUtils类来判断

org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#hasAspectAnnotation

private boolean hasAspectAnnotation(Class<?> clazz) {

   return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);

}

 

之后再执行

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass

protected boolean isInfrastructureClass(Class<?> beanClass) {

   boolean retVal = Advice.class.isAssignableFrom(beanClass) ||

         Pointcut.class.isAssignableFrom(beanClass) ||

         Advisor.class.isAssignableFrom(beanClass) ||

         AopInfrastructureBean.class.isAssignableFrom(beanClass);

   if (retVal && logger.isTraceEnabled()) {

      logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");

   }

   return retVal;

}

在这里判断是不是Advice、Pointcut、Advisor、AopInfrastructureBean类型

 

5.1.3 判断是否需要跳过

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip

@Override

protected boolean shouldSkip(Class<?> beanClass, String beanName) {

   // TODO: Consider optimization by caching the list of the aspect names

   List<Advisor> candidateAdvisors = findCandidateAdvisors();

   for (Advisor advisor : candidateAdvisors) {

      if (advisor instanceof AspectJPointcutAdvisor) {

         if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {

            return true;

         }

      }

   }

   return super.shouldSkip(beanClass, beanName);

}

 

5.1.3.1 获取候选的增强器(切面里面的Advice方法)

List<Advisor> candidateAdvisors

每一个封装的通知方法的增强器类型是InstantiationModelAwarePointcutAdvisor;

 

判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;

由于我们的增强器类型是InstantiationModelAwarePointcutAdvisor,不是AspectJPointcutAdvisor 类型的

 

5.1.3.2 永远返回false

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip

永远返回false

 

实际上我们的@Aspect切面类会加入到advisedBeans中

this.advisedBeans.put(cacheKey, Boolean.FALSE);

5.2. 创建对象

调用完postProcessBeforeInstantiation之后,

就要创建对象了

@Bean

public MathCalculator calculator(){

   return new MathCalculator();

}

这个calcalator对象是要创建为代理对象的,要把切面织入进来

//切面类加入到容器中

@Bean

public LogAspects logAspects(){

   return new LogAspects();

}

之后调用

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

这个方法的作用:如果bean被标识为(切点表达式)一个代理,那么就使用已配置的拦截器创建代理对象

@Override

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

   if (bean != null) {

      Object cacheKey = getCacheKey(bean.getClass(), beanName);

      if (!this.earlyProxyReferences.contains(cacheKey)) {

         return wrapIfNecessary(bean, beanName, cacheKey);

      }

   }

   return bean;

}

postProcessAfterInitialization

//如果需要的情况下包装

return wrapIfNecessary(bean, beanName, cacheKey);

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

// Create proxy if we have advice.

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

if (specificInterceptors != DO_NOT_PROXY) {

   this.advisedBeans.put(cacheKey, Boolean.TRUE);

   Object proxy = createProxy(

         bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

   this.proxyTypes.put(cacheKey, proxy.getClass());

   return proxy;

}



this.advisedBeans.put(cacheKey, Boolean.FALSE);

return bean;

在这里就创建proxy了

5.2.1 获取当前bean的所有增强器(通知方法)

Object[]  specificInterceptors

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {

   List<Advisor> candidateAdvisors = findCandidateAdvisors();

   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

   extendAdvisors(eligibleAdvisors);

   if (!eligibleAdvisors.isEmpty()) {

      eligibleAdvisors = sortAdvisors(eligibleAdvisors);

   }

   return eligibleAdvisors;

}

5.2.1.1 找到候选的所有的增强器(找哪些Advice方法是能够切入(切点)当前bean方法的)

List<Advisor> candidateAdvisors = findCandidateAdvisors();

5.2.1.2 获取到能在bean使用的增强器。

List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

5.2.1.3 给增强器排序

eligibleAdvisors = sortAdvisors(eligibleAdvisors);

5.2.2 保存当前bean在advisedBeans中;

this.advisedBeans.put(cacheKey, Boolean.TRUE);

5.2.3 如果当前bean需要增强,创建当前bean的代理对象;

Object proxy = createProxy(

      bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

5.2.3.1 获取所有增强器(Advice方法)

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

5.2.3.2 保存到proxyFactory

proxyFactory.addAdvisors(advisors);

5.2.3.3 创建代理对象:Spring自动决定

return proxyFactory.getProxy(getProxyClassLoader());

JdkDynamicAopProxy(config);jdk动态代理;

ObjenesisCglibAopProxy(config);cglib的动态代理;

 

org.springframework.aop.framework.DefaultAopProxyFactory

@Override

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

      Class<?> targetClass = config.getTargetClass();

      if (targetClass == null) {

         throw new AopConfigException("TargetSource cannot determine target class: " +

               "Either an interface or a target is required for proxy creation.");

      }

      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {

         return new JdkDynamicAopProxy(config);

      }

      return new ObjenesisCglibAopProxy(config);

   }

   else {

      return new JdkDynamicAopProxy(config);

   }

}

可以看到,targetClass是

5.2.3.4 给容器中返回当前组件使用cglib增强了的代理对象;

我们的calculator未实现接口,所以创建一个cglib增强了的代理对象

返回的就是一个增强了的代理对象

 

5.2.3.5 以后容器中获取到的就是这个组件的代理对象

执行目标方法的时候,代理对象就会执行增强方法的流程

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值