【Spring】Spring事务代理bean的创建源码分析--IOC注入

42 篇文章 0 订阅
6 篇文章 0 订阅

1  先来了解一下 SPI

  • org.springframework.beans.factory.config.BeanPostProcessor
  • org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
  • 都是对spring bean 初始化前后的处理。 注意区分实例化,设置和初始化。三个顺序依次进行。
  • 实验code 环境spring tx 5.1.6
  • @SpringBootApplication(scanBasePackages = {"com.xxx","com.yyy"})
    @EnableScheduling
    @Configuration
    @ImportResource(locations = {"${xxxxx.xml}"})
    @EnableAspectJAutoProxy(proxyTargetClass=true, exposeProxy=true)
    @EnableTransactionManagement
    public class MYApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }
    }

     

2 Spring事务代理AnnotationAwareAspectJAutoProxyCreator注册过程 // 初始化后拦截--创建代理

先回答下四个问题: 1 Spring Bean 什么时候注册? 2 如何注册的? 3 Spring bean 什么时候实例化? 4 如何实例化?

AnnotationAwareAspectJAutoProxyCreator : Spring Bean 什么时候注册? 如何注册的?

1 什么时候注册 --> refresh:org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors 531 解析注解导入Bean定义;
2 如何注册-->使用注解 EnableAspectJAutoProxy 启动registrar注册,并通过 org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions 接口完成注册;


AnnotationAwareAspectJAutoProxyCreator: Spring bean 什么时候实例化?如何实例化?

3 什么时候实例化-->org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors 534行 注册所有PostProcessors实例 (根据接口查询)
---->String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


4 如何实例化-->最终通过无参数反射实例化: No special handling: simply use no-arg constructor.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean 完成实例化。

 

它使用org.springframework.aop.framework.DefaultAopProxyFactory 作为默认的工厂类,里面包含了cglib和jdk的实现。

从refresh 开始:

  • --->// Invoke factory processors registered as beans in the context. factory processors 注册Spring Bean 到容器
  • --->org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
  • // 心得: 通过@Configuration 注册创建的Bean 定义,基本都是用工厂方法来创建bean实例!包含后面要讲的事务通知器
  • // org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor

  • --->// PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  • --->org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List

  • -->org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors

 

  • -->遍历Bean定义注册处理
  • -->执行到 ConfigurationClassPostProcessor

 

  • -->org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
  • -->org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
  • -->org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitions // 327行 reader

  • -->org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitions // 项目启动类

  • -->org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
  • --> // 启动类关联的registrar

  • // 其中一个注解 : @EnableAspectJAutoProxy(proxyTargetClass=true, exposeProxy=true)
  • --> org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions
  • // 执行的第一行代码
  • -->AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  • -->org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary
  • // 最终调用如下

  • // 接下来就是注册或者升级public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator"; Spring Bean
  • -->根据配置最终会根据优先级,把AnnotationAwareAspectJAutoProxyCreator作为internalAutoProxyCreator的Spring Bean
  • -->org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

  • -->AnnotationAwareAspectJAutoProxyCreator 基于注解的自动代理创建类的承关系

3 小结: 上面就把代理类AnnotationAwareAspectJAutoProxyCreator(AbstractAutoProxyCreator) Spring Bean 注册到了容器中。 那个Transaction的通知器(advisor)是什么时候注册到容器中的那?还有切点(pointcut)和织入(advice)

4 advisor BeanFactoryTransactionAttributeSourceAdvisor 通过工厂实例化到spring容器中

还是四个问题 Spring Bean  什么时候注册? 如何注册的?  什么时候实例化?如何实例化?
1 什么时候注册 -->@Configuration,所以bd是在refresh的531 invokeBeanFactoryPostProcessors 方法注册到容器中的
2 如何注册-->@Configuration
3 什么时候实例化-->org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors 534行 注册所有PostProcessors实例
4 如何实例化-->最终通过@Bean的工厂方法完成

也是从refresh 入口开始:

  • registerBeanPostProcessors 该入口大部分实例都是通过org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod来完成实例化

  • -->org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
  • -->org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
  • -->// 构建cache 等其他代理通知相关,会触发
  • -->org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
  • -->org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors
  • -->// 找到了事务通知器

  • // 事务通知器的创建使用工厂方法
  • -->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod

  • // 上面BeanDefinition 是通过org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration 这个类
  • // 由于实现了@Configuration,所以bd是在refresh的531 invokeBeanFactoryPostProcessors 方法注册到容器中的
  • // 指定工厂方法获取事务通知器
  • -->org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod
  • -->org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate // 实例化
  • 执行spring tx 5.1.6 中的创建逻辑:工厂方法(org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration#transactionAdvisor)

  • // 注意该事务通知器内部包含 org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut

  • // 工厂创建通知时,还给通知器赋值 advice 和 attributeSource (注意这里不是类内部直接调用,都是经过了cglib代理来调用获取结果设置的)

  • // 最后返回创建的事务通知器

5 小结:至此org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors 就完成事务通知bean的注册

即org.springframework.transaction.config.internalTransactionAdvisor(BeanFactoryTransactionAttributeSourceAdvisor)的创建

6 生成代理实例

  • // 这样bean 实例化后,如果需要织入事务,使用上面两个模块(BeanFactoryTransactionAttributeSourceAdvisor + AbstractAutoProxyCreator)就可以完成了。
  • --->org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType // 获取所有advisor

  • // 如果多个植入代理 则需要 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply
  • 进行匹配,如果匹配到事务代理(织入)则返回BeanFactoryTransactionAttributeSourceAdvisor
  • -->org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy // 完成代理创建 cglib或者jdk方式
  • -->org.springframework.transaction.interceptor.TransactionInterceptor // cglib 方式的callback 织入, 后面程序运行时,直接从
  • -->org.springframework.transaction.interceptor.TransactionInterceptor#invoke
  • -->org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction 执行带有事务的业务逻辑!这块可以参考
  • Spring AOP TX(Transactional) 事务处理源码阅读

  • // 代理最终实现
  • -->org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
  • -->org.springframework.aop.framework.ObjenesisCglibAopProxy // 本实例使用的方法
  • OR
  • -->org.springframework.aop.framework.JdkDynamicAopProxy

7 小结: 至此 BeanFactoryTransactionAttributeSourceAdvisor + AnnotationAwareAspectJAutoProxyCreator Spring事务代理bean的创建就全部完成了。

  • AbstractAutoProxyCreator 作用完成bean初始化后的post process,并负责寻找和匹配 advisors ;
  • BeanFactoryTransactionAttributeSourceAdvisor 负责 织入spring 事务,即tx;最终生成的bean实例就是含有事务(省去了硬编码)的实例。
  • 通过 @Configuration BeanFactoryTransactionAttributeSourceAdvisor 完成Spring Bean 注册;(refresh的531 invokeBeanFactoryPostProcessors 方法注册到容器中)
  • 通过 @EnableAspectJAutoProxy AnnotationAwareAspectJAutoProxyCreator 完成Spring Bean 注册(refresh的531 invokeBeanFactoryPostProcessors 作为注册到容器中的入口)-->org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions -->AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);第一行代码来完成 完成Spring Bean 注册。
  • 上层入口都是refresh的531行;
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自驱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值