SpringAOP的实现原理:0、总纲

本文作为Spring AOP系列的开篇,将提供一个总览,介绍Spring AOP的基本概念、核心组件以及其实现原理,帮助读者建立对Spring面向切面编程的全面认识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringAOP的作用:
     并将那些影响了多个类的公共行为封装到一个可重用模块,减少代码的耦合。
 
增强器的初始化是什么时候初始化的?
    第一次调用wrapIfNecessary(bean, beanName, cacheKey)方法的时候就会进行第一次初始化,此时会判断对象上是否有@Aspect 或者继承实现AOP相关方法的类,之后根据里面的方法进行构建增强器。
 
在SpringAOP的实现过程中,对bean增强的实现有两个地方:
    1、在实例化话完成之后会将实例化好的Bean封装为ObjectFactory加入到singletonFactories中。在需要获取此bean的时候会调 getEarlyBeanReference方法,内部会对实现 SmartInstantiationAwareBeanPostProcessor接口的处理器进行调用,对Bean进行处理,里面存在的 AnnotationAwareAspectJAutoProxyCreator中实现了 SmartInstantiationAwareBeanPostProcessor接口,在获取Bean的时候会调用 getEarlyBeanReference()方法,里面会判断此Bean是否被AOP的切面覆盖,是否需要增强,如果需要增强,则增强生产代理类进行返回。
    2、在初始化完成后都会调用 applyBeanPostProcessorsAfterInitialization, AnnotationAwareAspectJAutoProxyCreator也实现了 BeanPostProcessor。同样内部,会判断类是否需要增强处理。
 
下面我们先来说一下AOP的实现过程,之后再对细节进行详解。
AOP实现的过程:
    1、在实例化之前对于AOP相关的Bean和普通的Bean没有什么区别。
    2、对于支持循环依赖、并且是单例模式的bean,在bean实例化之后会加入到singletonFactories中。在其他Bean属性中需要获取这个bean的时候,就已经增强。
    3、对于没有没有增强的bean,则在初始化完成之后调用bean的后置处理器进行增强
    4、首先判断Bean是否需要增强。
    5、如果需要增强,首先获取可用的增强器。  详见: SpringAOP的实现原理:1、如何获取AOP增强器?
    6、之后根据Bean的信息和配置信息决定采用什么代理。 详见: SpringAOP的实现原理:2、AOP动态代理过程分析
    7、生产代理类进行返回。
 
每一个bean初始化必须调用initializeBean()方法,AOP的实现位置之一也是在此;另外一个位置在SingletonFactories中为解决循环依赖,获取AOP增强的Bean的时候,会在那个地方进行增强。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
  
   invokeAwareMethods(beanName, bean);
   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
    //初始化之前搞事情
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   try {
      //调用初始化方法  
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   if (mbd == null || !mbd.isSynthetic()) {
       //在此处进行AOP的增强,也在这个地方实现代理
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}
1、AbstractAutoProxyCreator.class
此处是代理的入口,我们将从这个方法一步步详细分析。   
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {
   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        //循环调用Bean的后置处理器
      result = beanProcessor.postProcessAfterInitialization(result, beanName);
   }
   return result;
}

//因为咱们研究是AOP处理增强的过程,其他的bean处理器暂时先不考虑,直接研究AnnotationAwareAspectJAutoProxyCreator,这个类是实现AOP的核心类。
//下面跟随方法一步步的深入学习。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) { //主要作用:过滤掉在前面已经被AOP增强过的bean(加入到SingletonFactories中被获取)
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

//此方法是AOP实现的最核心的方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 若此Bean已经在targetSourcedBeans里,说明是自己用户来自己做实例化,按照自己的方式进行增强。具体详见此类的postProcessBeforeInstantiation() 方法
// (postProcessBeforeInstantiation()中成功创建的代理对象都会将beanName加入到targetSourceBeans中)
// 为什么需要TargetSource? 详见:Spring 为什么需要TargetSource?    
   if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
 // 如果该Bean基础框架Bean或者免代理得Bean,那也不处理
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
// 逻辑同上,对于实现了Advice,Advisor,AopInfrastructureBean接口的bean,都认为是spring aop的基础框架类,不能对他们创建代理对象, 
// 同时子类也可以覆盖shouldSkip方法来指定不对哪些bean进行代理
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }
   // Create proxy if we have advice.  详见:SpringAOP的实现原理:如何获取AOP增强器?
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
    //详见:SpringAOP的实现原理:AOP动态代理的过程分析
      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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值