Spring 循环依赖时,对需要AOP中增强的类如何处理?

Spring 5.1.8 RELEASE

例:

@Aspect
@Component
public class LogAspects {
   //抽取公共的切入点表达式
   //1、本类引用
   //2、其他的切面引用
   @Pointcut("execution(public int com.aop.MathCalculator.*(..))")
   public void pointCut(){};
   
   //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
   @Before("pointCut()")
   public void logStart(JoinPoint joinPoint){
      Object[] args = joinPoint.getArgs();
      System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
   }
   
   @After("com.atguigu.aop.LogAspects.pointCut()")
   public void logEnd(JoinPoint joinPoint){
      System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
   }
   //JoinPoint一定要出现在参数表的第一位
   @AfterReturning(value="pointCut()",returning="result")
   public void logReturn(JoinPoint joinPoint,Object result){
      System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
   }
   
   @AfterThrowing(value="pointCut()",throwing="exception")
   public void logException(JoinPoint joinPoint,Exception exception){
      System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
   }
}

@Component
public class MathCalculator {
    @Autowired
    private AOPTest aopTest;

   public int div(int i,int j){
      System.out.println("MathCalculator...div...");
      return i/j;    
   }
}

@Component
public class AOPTest {
    
    @Autowired
    private MathCalculator mathCalculator;
}
请大家考虑一个问题:
       正常属性依赖注入的时候,如何解决循环依赖?
       主要方式,通过在实例化完成之后将实例加入到singletonFactories中,后边的处理就是对实例进行赋值和初始化。比如:A依赖B,B依赖A。在A填充属性的时候获取依赖的Bean B。在这个时候B发现依赖着A,这个时候获取A就从singletonFactories获取出来进行返回赋值,从而解决循环依赖的问题。
        但是对于AOP需要增强的Bean应该如何处理循环依赖的问题?    
       在实例话之前,AOP增强的Bean和普通的Bean没有什么区别,加入到singletonFactories之后。当有其他Bean依赖此Bean的时候,就需要获取Bean的实例,都要调用
getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean);    
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}

在内部都调用了实现SmartInstantiationAwareBeanPostProcessor接口的处理器。

其中有一个处理器,AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor。

下面我们将来分析一下此处理器对Bean的不同的处理

AbstractAutoProxyCreator#getEarlyBeanReference 

public Object getEarlyBeanReference(Object bean, String beanName) {
   Object cacheKey = getCacheKey(bean.getClass(), beanName);
   this.earlyProxyReferences.put(cacheKey, bean);
   //主要作用,提前给依赖的Bean返回一个代理对象,在初始化完成之后不用再次调用了。 
   return wrapIfNecessary(bean, beanName, cacheKey);
}

增强的过程具体详见后续文章:SpringAOP的实现原理

所以在Bean依赖处理的时候就会将AOP增强的Bean就增强了,不需要等到初始化完成之后。

 
 
 

你可能感兴趣的:(Spring源码解析,Spring问题)