【spring源码】AOP底层源码分析

【spring源码】AOP底层源码分析

        • 1.测试用例
        • 2.AOP流程概述
        • 3.AOP源码分析

注:其他一些spring源码解读,如果有需要,可以参考:

  • 【Spring源码】 后置处理器BeanPostProcessor底层原理分析
  • 【spring源码】spring声明式事务底层源码分析
  • 【spring源码】ApplicationListener事件监听底层原理

spring的AOP是什么不在赘述,以下内容默认大家会使用AOP,我们今天来扒源码

1.测试用例

  • 引入必要依赖:
 
        
            org.springframework
            spring-context
            4.3.12.RELEASE
        
        
            junit
            junit
            4.12
        
        
            org.springframework
            spring-aspects
            4.2.2.RELEASE
        
    
  • 写个测试用的业务类:
/**
 * todo
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/7
 */
public class MathCalculator {

    public int test(int i,int j){
        return i/j;
    }
}
  • 再写个切面类:
/**
 * 日志切面
 * @Aspect: 告诉Spring当前类是一个切面类
 * @author wangjie
 * @version V1.0
 * @date 2020/1/7
 */

@Aspect
public class LogAspects {


    /**
     * 抽取公共的切入点表达式
     *  1、本类引用
     *  2、其他的切面引用
     */
    @Pointcut("execution(public int com.code.aop.MathCalculator.*(..))")
    public void pointCut(){};

    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+ Arrays.asList(args)+"}");
    }
    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
    }
    /**
     * JoinPoint一定要出现在参数表的第一位
     * @param joinPoint
     * @param result
     */
    @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+"}");
    }
}

  • 这是个日志切面类,主要用于打印日志。
  • 然后写配置:
Configuration
@EnableAspectJAutoProxy
public class AOPConfig {

    @Bean
    public MathCalculator mathCalculator(){
        return new MathCalculator();
    }

    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
}

  • 最后搞个测试类:
/**
 * todo
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/7
 */
public class IOCTest_AOP {

    @Test
    public void test01(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AOPConfig.class);

        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);

        mathCalculator.test(1, 1);
        mathCalculator.test(1, 0);

        applicationContext.close();
    }
}
  • 运行结果:
test运行。。。@Before:参数列表是:{[1, 1]}
test结束。。。@After
test正常返回。。。@AfterReturning:运行结果:{1}
test运行。。。@Before:参数列表是:{[1, 0]}
test结束。。。@After
test异常。。。异常信息:{java.lang.ArithmeticException: / by zero}

java.lang.ArithmeticException: / by zero

	at com.code.aop.MathCalculator.test(MathCalculator.java:13)
	at com.code.aop.MathCalculator$$FastClassBySpringCGLIB$$96b23dea.invoke()
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
	省略多余异常信息。。。。


Process finished with exit code -1

2.AOP流程概述

具体源码太过繁杂,正式扒源码之前,我们先以上帝视角对AOP流程做个概述,以下流程涉及的所有类和方法具体解释我们在下个章节慢慢聊。

  • 测试类中的new AnnotationConfigApplicationContext(AOPConfig.class);会创建spring IOC容器,
  • 这个IOC容器创建过程中会对配置类AOPConfig中配置的bean做初始化
  • 过程中配置类AOPConfig上的@EnableAspectJAutoProxy注解会开启AOP功能
  • 具体过程@EnableAspectJAutoProxy 会给IOC容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
  • AnnotationAwareAspectJAutoProxyCreator我们一直往上扒其父类会发现,它是一个后置处理器
  • 然后在IOC容器创建过程中会有个registerBeanPostProcessors方法用来注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator对象
  • 注册完后,IOC创建过程中还有另一个方法finishBeanFactoryInitialization(),它的作用是初始化剩下的单实例bean(省略了很多步骤)
  • 在这个方法里,AnnotationAwareAspectJAutoProxyCreator会拦截bean的创建过程,去判断业务bean是不是要增强?(是不是切点)
  • 是的话,就会包装增强器(Advisor),给业务bean创建一个代理对象(cglib)(我们今天不聊jdk代理)
  • 然后等这个IOC容器创建完成,真正执行方法是时候,去执行方法的就是cglib代理对象
  • 这个代理对象里面保存了详细信息(比如增强器,目标对象,等等),最后的执行者是CglibAopProxy.DynamicAdvisedInterceptor.intercept()
  • 它会得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
  • 利用拦截器的链式机制,依次进入每一个拦截器进行执行:
  • 效果:
  •  			正常执行:前置通知-》目标方法-》后置通知-》返回通知
    
  •  			出现异常:前置通知-》目标方法-》后置通知-》异常通知
    

3.AOP源码分析

3.1 @EnableAspectJAutoProxy分析

  • 有上面的流程概述打底,我们先看一下@EnableAspectJAutoProxy这个注解,看它做了什么,有什么作用
    【spring源码】AOP底层源码分析_第1张图片
  • 关键点已经标红,就是那个@Import注解:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
  • AspectJAutoProxyRegistrar 实现了一个ImportBeanDefinitionRegistrar,这个接口是用来做什么的?

【spring源码】AOP底层源码分析_第2张图片

  • 它是用来自定义注册bean的,我们回过头看AspectJAutoProxyRegistrar ,它实现了那个方法:
    【spring源码】AOP底层源码分析_第3张图片
  • 进入方法,看我标注的那行代码,一直跟下去:
    在这里插入图片描述
  • 它注册了一个叫 AnnotationAwareAspectJAutoProxyCreator的组件
  • 我们再看看AnnotationAwareAspectJAutoProxyCreator是做什么的:
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {...}
  • 它继承了AspectJAwareAdvisorAutoProxyCreator ,继续跟:
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {...}
  • AspectJAwareAdvisorAutoProxyCreator又继承了AbstractAdvisorAutoProxyCreator ,再跟:
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
  • 又继承了AbstractAutoProxyCreator ,再跟:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {...}
  • 又继承了ProxyProcessorSupport 和实现了SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware
  • SmartInstantiationAwareBeanPostProcessor再跟下去会发现:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {.....}
  • 而BeanFactoryAware 我们打开
public interface BeanFactoryAware extends Aware {
   void setBeanFactory(BeanFactory var1) throws BeansException;
}
  • 关键点来了:
  • BeanPostProcessor 后置处理器,不知道大家熟不熟悉,它的作用主要是在bean的初始化前和初始化后工作,祥见:【Spring源码】 BeanPostProcessor底层原理分析
  • BeanFactoryAware 可以往组件中注入BeanFactory ,自动装配BeanFactory
  • 找到了这里,如果你再回过头从后往前扒源码,你就会在AbstractAutoProxyCreator中发现有关后置处理器方法实现的逻辑
  • 并会在AbstractAdvisorAutoProxyCreator中发现setBeanFactory()自动装配BeanFactory的方法
  • 而且在setBeanFactory()方法中又调用了AnnotationAwareAspectJAutoProxyCreator的initBeanFactory()方法(后面要用)
  • 等我们了解了AnnotationAwareAspectJAutoProxyCreator大概可能的作用是在bean初始化前后搞事情后,我们再从头撸源码。

3.2 AOP原理分析

  • 我们从这行代码开始:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AOPConfig.class);
  • 创建IOC容器
  • 点进去:
 public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this();
        //解析配置类,注册bean
        this.register(annotatedClasses);
        //spring的核心,在这个方法里,Spring完成了容器的初始化
        this.refresh();
    }
  • 熟悉Spring源码的对refresh()这个方法应该不会陌生,spring的核心,我们点进去:
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            //容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
            this.prepareRefresh();
            //获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
               //配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器等
                this.postProcessBeanFactory(beanFactory);
                //模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
                //允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展 
                //prepareBeanFactory(beanFactory)的方法。
                // 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)。
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
                this.registerBeanPostProcessors(beanFactory);
                //初始化国际化工具类MessageSource
                this.initMessageSource();
                //初始化事件广播器
                this.initApplicationEventMulticaster();
                //模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
                this.onRefresh();
                //注册监听器,广播early application events
                this.registerListeners();
                //实例化所有剩余的(非懒加载)单例
                //实例化的过程各种BeanPostProcessor开始起作用。
                this.finishBeanFactoryInitialization(beanFactory);
                //refresh做完之后需要做的其他事情。
                //清除上下文资源缓存(如扫描中的ASM元数据)
                //初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
                //发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }
  • 注释已经很详细,如果想进一步看每一步详解,可见:
  • 【spring源码】spring容器IOC底层源码分析
  • 今天我们来看 this.registerBeanPostProcessors(beanFactory);这行代码,实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
  • 还记得之前我们一直对AnnotationAwareAspectJAutoProxyCreator刨根问底看得的那个BeanPostProcessor吗?它就在这里用到了。
  • 我们跟下去:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
       //先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        //给容器中加别的BeanPostProcessor
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
        List priorityOrderedPostProcessors = new ArrayList();
        List internalPostProcessors = new ArrayList();
        List orderedPostProcessorNames = new ArrayList();
        List nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;
        String ppName;
        BeanPostProcessor pp;
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();

        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();

        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

  • 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
  • 给容器中加别的BeanPostProcessor
  • 优先注册实现了PriorityOrdered接口的BeanPostProcessor;
  • 再给容器中注册实现了Ordered接口的BeanPostProcessor;
  • 注册没实现优先级接口的BeanPostProcessor;
  • 注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
  • 之前我们跟AnnotationAwareAspectJAutoProxyCreator到最后有个ProxyProcessorSupport 不知道大家还有没有印象
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
  • 它实现了Ordered接口,所以会走:
    【spring源码】AOP底层源码分析_第4张图片
  • 继续往下跟,创建bean会先从容器里获取一下,获取不到就创建,创建之前会判断是不是单实例的:
    【spring源码】AOP底层源码分析_第5张图片
  • 如果是的话,调用createBean():
  • 再向下,一直到一个doCreateBean()方法中:
    【spring源码】AOP底层源码分析_第6张图片
  • populateBean;给bean的各种属性赋值
  • initializeBean:初始化bean
  • 了解spring IOC初始化的兄弟应该对这个过程不陌生,在initializeBean方法里:
    【spring源码】AOP底层源码分析_第7张图片
  • invokeAwareMethods():处理Aware接口的方法回调,像上面说的那个实现了BeanFactoryAware接口的方法,setBeanFactory()方法自动装配BeanFactory:
    在这里插入图片描述
  • 这里这个bean我们聊的是AnnotationAwareAspectJAutoProxyCreator,我们来看看它里面的setBeanFactory()方法
public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory);
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
        } else {
            this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
        }
    }
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        if (this.aspectJAdvisorFactory == null) {
            this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
        }

        this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
  • 对,除了beanFactory,它还搞了个BeanFactoryAspectJAdvisorsBuilder(aspectJAdvisorFactory 是其id)
  • BeanFactoryAspectJAdvisorsBuilder是一个Spring AOP内部工具类,该工具类用来从bean容器,也就是BeanFactory中获取所有使用了@AspectJ注解的bean,最终用于自动代理机制(auto-proxying),最核心的逻辑在其方法buildAspectJAdvisors中,该方法查找容器中所有@AspectJ注解的bean,然后将其中每个advice方法包装成一个Spring Advisor。最终结果以一个List的形式返回给调用者,有兴趣可以去看看,这里不再赘述。
  • 接着往下看:
  • applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
    在这里插入图片描述
  • 遍历执行容器内所有BeanPostProcessor接口实现类的postProcessBeforeInitialization方法。
  • invokeInitMethods();执行自定义的初始化方法,这个没什么好聊的
  • applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
    在这里插入图片描述
  • 跟applyBeanPostProcessorsBeforeInitialization()一脉相承,不再赘述。
  • 最后一路返回:
    【spring源码】AOP底层源码分析_第8张图片
  • 把BeanPostProcessor注册到BeanFactory中。
  • 走到这儿才算是把AnnotationAwareAspectJAutoProxyCreator创建和注册完。
  • 等所有实现了BeanPostProcessor的bean都搞完,refresh()中的this.registerBeanPostProcessors(beanFactory)这行代码才算完成。
  • 怕大家忘了,我把refresh()方法再贴一遍:
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            //容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
            this.prepareRefresh();
            //获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
               //配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器等
                this.postProcessBeanFactory(beanFactory);
                //模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
                //允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展 
                //prepareBeanFactory(beanFactory)的方法。
                // 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)。
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
                this.registerBeanPostProcessors(beanFactory);
                //初始化国际化工具类MessageSource
                this.initMessageSource();
                //初始化事件广播器
                this.initApplicationEventMulticaster();
                //模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
                this.onRefresh();
                //注册监听器,广播early application events
                this.registerListeners();
                //实例化所有剩余的(非懒加载)单例
                //实例化的过程各种BeanPostProcessor开始起作用。
                this.finishBeanFactoryInitialization(beanFactory);
                //refresh做完之后需要做的其他事情。
                //清除上下文资源缓存(如扫描中的ASM元数据)
                //初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
                //发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }
  • 前面注册完了,后面就要用到它了,我们来看 this.finishBeanFactoryInitialization(beanFactory)这行代码,实例化所有剩余的(非懒加载)单例,像我们测试用例中的业务类MathCalculator就会走到这里面:
    【spring源码】AOP底层源码分析_第9张图片
  • 前面不用管,我们点进preInstantiateSingletons()方法,在这个方法里面一顿操作:getBean->doGetBean()->getSingleton()->创建bean
  • 这次看着这个流程熟悉不,跟上面创建AnnotationAwareAspectJAutoProxyCreator大同小异,我们直接进createBean()方法:
    【spring源码】AOP底层源码分析_第10张图片
  • 这次我们可以关注一下resolveBeforeInstantiation()方法,希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能返回就继续执行:
    【spring源码】AOP底层源码分析_第11张图片
  • 点进去:
    【spring源码】AOP底层源码分析_第12张图片
  • 拿到所有的后置处理器。
  • 判断如果是InstantiationAwareBeanPostProcessor;(注意,我们之前聊的创建并注册的那个后置处理器AnnotationAwareAspectJAutoProxyCreator其就属于此类型)
  • 就执行postProcessBeforeInstantiation
    【spring源码】AOP底层源码分析_第13张图片
  • advisedBeans.containsKey(cacheKey)判断当前bean是否在advisedBeans中(保存了所有需要增强bean),MathCalculator不在,跳过。
  • isInfrastructureClass(beanClass)判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),返回false;
  • shouldSkip(beanClass, beanName)判断是否要跳过,返回false;
  • getCustomTargetSource(beanClass, beanName)是否自定义TargetSource,跟MathCalculator没关系,返回null。
  • 重新回到createBean()方法:
    【spring源码】AOP底层源码分析_第14张图片
  • resolveBeforeInstantiation(beanName, mbdToUse)没能返回代理对象,我们只能继续执行doCreateBean(beanName, mbdToUse, args);
  • 一直点下去,点进initializeBean()方法:
    【spring源码】AOP底层源码分析_第15张图片
  • 这个方法我们上面已经聊过一次,不再多言,这次我们只看applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName):
    【spring源码】AOP底层源码分析_第16张图片
  • 获取所有BeanPostProcessors实现类执行其后置处理器,还记得我们上面注册的那个后置处理器AnnotationAwareAspectJAutoProxyCreator吗?打开它的postProcessAfterInitialization方法()
    【spring源码】AOP底层源码分析_第17张图片
  • wrapIfNecessary(bean, beanName, cacheKey)是否需要包装:
    【spring源码】AOP底层源码分析_第18张图片
  • 一堆判断,跟上面那次差不多,只是有取反,会进入getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null)方法,该方法会获取当前bean的所有增强器(通知方法),像我们定义在切面类里对MathCalculator的增强器,在这里都会被获取。
  • 最后createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)):
    【spring源码】AOP底层源码分析_第19张图片
  • 保存到proxyFactory中
  • 创建代理对象:
    【spring源码】AOP底层源码分析_第20张图片
  • JdkDynamicAopProxy(config);jdk动态代理;
  • ObjenesisCglibAopProxy(config);cglib的动态代理;
  • 不指定配置的话,两者由spring决定创建那种,默认情况下如果目标类有实现接口会使用 JdkDynamicAopProxy,否则选择Cglib
  • 聊到这IOC终于创建完了,这时候IOC容器中目标类的实例就是那个代理类。

3.3 目标方法的执行

  • 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,等)
  • 真正执行方法的是CglibAopProxy.DynamicAdvisedInterceptor.intercept()
    【spring源码】AOP底层源码分析_第21张图片
    -根据ProxyFactory对象获取将要执行的目标方法拦截器链;getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    【spring源码】AOP底层源码分析_第22张图片
  • List interceptorList保存所有拦截器,大小是5,一个默认的ExposeInvocationInterceptor 和 我们切面里写的4个增强器;
  • 遍历所有的增强器,将其转为Interceptor;
  • 返回拦截器链。
  • 执行(new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed()
    【spring源码】AOP底层源码分析_第23张图片
  • 如果没有拦截器执行执行目标方法,或者拦截器的索引和-1大小一样(指定到了最后一个拦截器)执行目标方法;
  • 否则链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
  • 拦截器链的机制,保证通知方法与目标方法的执行顺序;
  • 这种模式大家应该不会陌生,如果一时想不明白,可以看下面图解:
    【spring源码】AOP底层源码分析_第24张图片
    【完】
    注:文章内所有测试用例源码:https://gitee.com/wjie2018/source-code.git

你可能感兴趣的:(源码分析,spring,java,spring,java,aop)