Spring Aop 源码解析

个人学习笔记
启动Aop注解

@EnableAspectJAutoProxy

@Import(AspectJAutoProxyRegistrar.class)给容器中导入组件AspectJAutoProxyRegistrar
在这里插入图片描述
利用AspectJAutoProxyRegistrar 自定义给容器注册名叫internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator 的Bean
在这里插入图片描述
查看AnnotationAwareAspectJAutoProxyCreator 继承关系

AnnotationAwareAspectJAutoProxyCreator
    AspectJAwareAdvisorAutoProxyCreator
        AbstractAdvisorAutoProxyCreator
            AbstractAutoProxyCreator
                ProxyProcessorSupport->Ordered接口
                SmartInstantiationAwareBeanPostProcessor接口->BeanPostProcessor
                BeanFactoryAware接口                

关注BeanPostProcessor后置处理器和BeanFactoryAware自动装配接口
AbstractAutoProxyCreator.后置处理器逻辑
AbstractAutoProxyCreator.setBeanFactory(BeanFactory)

流程

1、传入配置类,创建IOC容器。new AnnotationConfigApplicationContext(AopConfig.class);
2、注册配置类,调用refresh();刷新容器
3、registerBeanPostProcessors(beanFactory);注册bean的后置处理器,方便拦截bean的创建
    1、获取到IOC已经定义了,需要创建对象的所有的BeanPostProcessor
    2、给容器中加入其他需要的 PostProcessor  -》beanFactory.addBeanPostProcessor()
    3、将获取到所有的bean分类存储
    4、先注册实现了PriorityOrdered接口的BeanPostProcessor
    56、最后注册什么都没有的BeanPostProcessor
    7、注册BeanPostProcessor,就是创建BeanPostProcessor对象保存到容器中
    注册internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator过程
        getBean->doGetBean()->createBean()->doCreateBean()
        1、创建bean实例
        2、populateBean(beanName, mbd, instanceWrapper);给bean的属性赋值
        3、initializeBean(beanName, exposedObject, mbd);初始化bean
            1、invokeAwareMethods()处理aware接口的方法回调
            2、applyBeanPostProcessorsBeforeInitialization(),应用后置处理器的beanProcessor.postProcessBeforeInitialization();初始化之前调用
            3、invokeInitMethods() 执行自定义初始化
            4、applyBeanPostProcessorsAfterInitialization() ,应用后置处理器的beanProcessor.postProcessAfterInitialization();;初始化之后调用
         创建完成 BeanPostProcessor【AnnotationConfigApplicationContext->InstantiationAwareBeanPostProcessor】
    8、把注册好的BeanPostProcessor注册到BeanFactory中
        beanFactory.addBeanPostProcessor()
4、finishBeanFactoryInitialization(beanFactory);完成beanFactory初始化工作,创建剩下的单实例bean
    AnnotationAwareAspectJAutoProxyCreator会在bean创建之前进行拦截,调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
    1、遍历所有的bean,依次创建对象
        getBean()->doGetBean()->getSingleton()

    2、创建bean
        1、先从缓存中获取bean,如果有直接使用,没有就创建,只要创建好的bean都会被缓存起来。
        2、createBean,创建bean,AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前尝试返回bean实例。
            【BeanPostProcessor是在bean对象创建完成初始化前后调用】
            【InstantiationAwareBeanPostProcessor是在创建bean实例之前先尝试用后置处理器返回对象   】
            resolveBeforeInstantiation(beanName, mbdToUse);
            根据注释希望在这返回一个代理对象,如果不能就继续
            1、后置处理器先尝试返回对象
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor
            就执行postProcessBeforeInstantiation
                1、在每个bean创建之前调用postProcessBeforeInstantiation
                只关心CalService和LogAspect
                2、判断是否在advisedBeans中,advisedBeans保存了所有的增强bean
                3、判断bean是否是基础类,Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否有@Aspect是否是切面;
                4、是否需要跳过
                     获取候选的增强器(切面里面的通知方法),判断每个增强器是否是AspectJPointcutAdvisor类型

            if (bean != null) {
                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
    3、doCreateBean(beanName, mbdToUse, args);真正的创建bean
        1、调用postProcessAfterInitialization 创建bean
                return wrapIfNecessary(bean, beanName, cacheKey);包装如果需要的话
                1、获取当前bean的所有的增强器(通知方法)
                    1、找到候选的所有的增强器(找到哪些通知方法需要切入当前bean方法)
                    2、找到能在bean使用的增强器
                    3、给增强器排序
                2、保存当前bean在advisedBeans中
                3、如果当前bean需要增强,,创建当前bean的代理对象
        2、给容器中返回使用了cglib增强的代理对象
    4、目标方法执行
        容器中保存了组件的代理对象,这个对象保存了详细信息(比如增强器,目标对象等等)
        1、CglibAopProxy.intercept()拦截目标方法的执行
        根据ProxyFactory获取将要执行目标方法的拦截器链
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            如果没有拦截器链直接执行目标方法
            如果有就把目标对象,目标方法,拦截器链等 创建一个CglibMethodInvocation并调用proceed()
            retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
        2、拦截器链的触发过程,
            如果没有拦截器链执行目标方法,或者当拦截器的索引和拦截器链数组-1大小相等(执行到了最后一个拦截器链),执行目标方法
                if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                    return invokeJoinpoint();
                }
            链式获取每个拦截器,拦截器执行invoke(),每个拦截器等待下一个拦截器执行完成返回以后再来执行,
            链式调用,保证了通知方法和目标方法的执行顺序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值