• Spring AOP部分源码分析


    Spring源码流程分析-AOP相关

    根据Spring源码整理,其中Calculator为自定义的实现方法。

    AnnotationConfigApplicationContext()加载配置类的流程

    1. register()传入配置类,准备IoC容器
    2. 注册配置类之后,refresh()刷新创建的容器
      1. invokeBeanFactoryPostProcessors()
      2. registerBeanPostProcessors()注册Bean的后置处理器以拦截bean
        1. 先获取IoC容器中已经定义了的需要创建的BeanProceesorNames
        2. 注册BeanPostProcessorChecker,该检查器在BeanPostProcessor实例化期间创建bean时记录信息消息,例如,当bean不符合所有BeanPostProcessor的处理条件时进行记录。
        3. 将BeanPostProcessor按照实现的PriorityOrdered,Ordered和其他接口进行分类
        4. 首先注册实现PriorityOrdered接口的BeanPostProccessor
        5. 然后注册实现了Ordered接口的BeanPostProccessor
          1. 根据PostProcessorName获取Bean
            1. 创建Bean实例(这里获取的是一个BeanWrap对象,并不是Bean)
              1. 给BeanPostProcessors返回一个代理对象替代目标bean实例的机会
              2. 真正创建Bean实例(PostProcessor本身也是一个Bean实例)
                1. 创建一个BeanWrapper(bean包装类)
                2. 创建Bean实例(输入internalAutoProxyCreator)
                  1. 获取到真实的beanClass(这里是AnnotationAwareAspectJAutoProxyCreator)
                  2. 如果没有特殊的处理,仅适用无参构造方法进行实例化
                    1. 先获取实例化的策略(通过getInstantiationStrategy()),用以实例化Bean
                      1. 使用CGLIB进行实例化(如果没有重写的情况下使用)
                      2. 使用反射机制进行实例化
            2. 通过BeanWrap获取包装的bean对象
            3. 通过BeanWrap获取包装的bean对象的类型
            4. 后置处理器可以修改合并的bean定义。
              1. 获取定义好的全部PostProcessor,如果有MergedBeanDefinitionPostProcessor处理器,则进行合并。(eg.合并了ApplicationListenerDetector)
            5. 给bean的各种属性赋值(populateBean)
            6. 初始化Bean(initializeBean)
              1. 调用Aware方法
                1. 对实现了BeanNameAware接口的bean进行设置beanName
                2. 对实现了BeanClassLoaderAware接口的Bean设置beanClassLoader
                3. 对实现了BeanFactoryAware接口的Bean设置beanFactory
              2. 在初始化前调用BeanPostProcessors处理器(applyBeanPostProcessorBeforeInitialization)
                1. 获取全部的BeanPostProcessors
                2. 依次执行其中的postProcessBeforeInitialization()方法
                  1. 调用AwareInterface方法:
                  2. ApplicationContextAwareProcessor时的AwareInterface方法如下:
                    1. EnvironmentAware->setEnvironment()
                    2. EmbeddedValueResolverAware->setEmbeddedValueResolver()
                    3. ResourceLoaderAware->setResourceLoader()
                    4. ApplicationEventPublisherAware->setApplicationEventPublisher()
                    5. MessageSourceAware->setMessageSource()
                    6. ApplicationContextAware->setApplicationContext()
              3. 调用Init方法:
                1. 先判断是否是InitializingBean(如果是,执行以下内容)
                2. 获取initMethodName
                3. 调用自定义的初始化方法
              4. 在初始化方法后调用BeanPostProcessors处理器(applyBeanPostProcesssorAfterInitialization)
          2. 判读并标记是否是InstantiationAwareBeanPostProcessor(实例化处理器)
          3. 判断并标记是否是DestructionAwareBeanPostProcessor(销毁处理器)
          4. 添加到BeanPostProccessor列表中
        6. 注册没有实现优先级接口的BeanPostProccessor
      3. 实例化剩下的非lazy-init单例(finishBeanFactoryInitialization->preInstantiateSingletons)
        1. 获取容器中全部的Bean名称
        2. 判断是否是FactoryBean,
        3. 如果不是FactoryBean直接获取创建Bean对象(getBeanName)
          1. 先检查单例缓存中是否存在手动注册的单例,(第一次创建单例,返回都是null)
          2. 创建bean实例
            1. 给BeanPostProcessors返回一个代理对象替代目标bean实例的机会
              1. 如果是InstantiationAwareBeanPostProcessor,就执行applyBeanPostProcessorsBeforeInstantiation。
            2. 然后调用doCreateBean()进行真实Bean的创建。

    增强Calculator bean的流程

    在refresh()->finishBeanFactoryInitialization中完成

    1. 实例化剩余的非懒加载的单例
      1. 获取全部的beanNames,循环遍历
      2. 获取bean定义(getBean(calculator))
        1. 先尝试从缓存中获取bean(第一次获取,为null)
        2. 标记bean已经被创建
        3. 获取bean依赖的bean并先进行创建(这里为null)
        4. 创建bean实例->createBean(beanName, mbd, args)
        5. 给BeanPostProcessors尝试返回代理对象的机会(resolveBeforeInstantiation)
          1. 进入Instantiation前置方法,执行前置处理器
            1. 获取全部的处理器,循环遍历,如果为InstantiationAwareBeanPostProcessor则调用前置处理器方法
            2. 当执行到AnnotationAwareAspectJAutoProxyCreator,执行器前置方法:
              1. 如果有自己定义的TargetSource则创建一个代理,这里为null(并没有起到实际的作用)
        6. doCreateBean()创建bean实例
          1. createBeanInstance()使用工厂方法(instantiateUsingFactoryMethod)调用Calculator构造方法,进行初始化构造
            1. 创建一个BeanWrapperImpl实现类
            2. 初始化BeanWrapperImpl(此时只包含默认值)
            3. 获取FactoryBeanName:cap10MainConfig
            4. 获取factoryBean:cap10MainConfig(被加强的)
            5. 当不使用任何factoryMethod和参数,尝试所有匹配给定参数的方法
            6. 获取全部符合条件方法(匹配到calculator())
            7. 如果只有一个符合条件的方法,将calculator()存入mdb.resolvedConstructorOrFactoryMethod
            8. instantiate()实例化bw bean装饰类
            9. 使用CGLIB的instantiate进行实例化
              1. 调用invoke()->intercept:cglibMethodProxy.invokeSuper->...->Calculator()构造函数
          2. 允许后置处理器修改合并的bean定义:applyMergedBeanDefinitionPostProcessors()
            1. 如果是MergedBeanDefinitionPostProcessor则执行其postProcessMergedBeanDefinition()
          3. populateBean给bean实例赋值
            1. 在配置属性前给InstantiationAwareBeanPostProcessors修改bean的机会,通过postProcessAfterInstantiation方法
            2. 检查如果实现了InstantiationAwareBeanPostProcessor,通过postProcessProperties获取PropertyValues
            3. applyPropertyValues应用属性值
          4. initializeBean():执行Bean初始化方法
            1. 调用Aware方法:invokeAwareMethods()(这里不存在Aware方法直接跳过)
            2. 调用Initialization前置处理器:applyBeanPostProcessorsBeforeInitialization()
              1. 获取全部的BeanPostProcessors,循环调用postProcessBeforeInitialization()--这里没做具体操作
            3. 调用初始化方法
              1. 判断bean类型是否是InitializingBean(这里跳过)
              2. 获取初始化方法
            4. 调用Initialization后置处理器
              1. 获取全部的BeanPostProces,循环遍历执行postProcessAfterInitialization()
              2. 如果需要,包装给定的bean,例如,当需要被代理。eg:当遇到AnnotationAwareAspectJAutoProxyCreator时,执行wrapIfNecessary():返回一个代理对象
                1. 创建代理
                  1. 获取全部的拦截器
                  2. 创建Proxy:
                    1. 构建增强器advisors
                    2. 添加到ProxyFactory
                    3. 创建Proxy(getProxy()->createAopProxy().getProxy()) 这里返回一个cglibaop代理
              3. 经过上一阶段的处理,返回的wrappedBean实际上变成了增强过后的代理对象,最终向上传递最后实际创建的是一个增强的代理对象。

    AOP的调用流程

    div(4, 1)入口:

    1. 进入拦截intercept()方法
    2. 获取TargetSource(包含Calculator)
    3. 获取目标类,target=targetSource.getTarget()
    4. 获取目标类对象类型
    5. 获取拦截链 getInterceptorsAndDynamicInterceptionAdvice()
      1. 尝试从缓存中获取方法列表
      2. 如果没有,则从advisorChainFactory中获取(getInterceptorsAndDynamicInterceptionAdvice())
      3. 获取advisors列表,并创建interceptorList
      4. 循环遍历advisors,如果类型为PointCutAdvisor进行处理:(如果匹配为真,则添加到interceptorsList中)
        1. 由advice获取拦截方法列表
        2. 添加到interceptorList列表中
      5. 添加到methodCache中
    6. 如果没有拦截器链直接执行目标方法
    7. 如果有,创建一个方法调用(CglibMethodInvocation(..).proceed())
      1. 链式获取每一个拦截器,执行每一个拦截器的invoke方法,该拦截器等待下一个拦截器返回以后再执行。

    小结

    @EnableAspectJAutoProxy

    开启AOP功能:主要在容器中注入了一个组件AnnotationAwareAspectJAutoProxyCreator对象

    简述流程

    1. registerBeanPostProcessors():注册后置处理器-其中创建了AnnotationAwareApectJAutoProxyCreator对象
    2. finishBeanFactoryInitialization():初始化剩余的单实例bean
      1. 创建业务逻辑和切面组件
      2. AnnotationAwareAspectJAutoProxyCreator:拦截组件的创建过程
      3. 判断组件是否需要增强,如果需要增强,返回一个代理对象
    3. 执行目标方法
      1. 代理对象执行目标方法
      2. CglibAopProxy.intercept()拦截
        1. 获取一个拦截链
        2. 利用链式拦截器,依次执行拦截器内方法
        3. 执行顺序:
          1. 正常:前置->目标方法->后置->返回通知
          2. 异常:前置->目标方法->后置->异常通知
  • 相关阅读:
    JS_Boolean Logic
    js String
    .Net之路(二)简介
    自考 操作系统概论计算机系统
    IT大学生最重要的五个能力
    数据库表及字段命名规范
    简述MVC分层
    .Net之路(一)概述
    设计模式(4)迭代器模式
    .Net之路(三)如何连接数据库?
  • 原文地址:https://www.cnblogs.com/NinWoo/p/9923467.html
Copyright © 2020-2023  润新知