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行;