Spring事物(二)----基于注解源码分析之1
源码解析流程
源码从哪里看起?当然是配置文件作为入口。
打开xml的配置,找到如下片段,就是这么简单的配置,怎么看呢。
链接annotataion-driven标签,发现跳转到jar包的xsd文件了,既然是标签,按惯性思维,应该是要解析标签。打开后的目录结构,哪个是我们需要的呢,不熟悉spring的标签解析请自行度娘。 打开spring.handlers文件,TxNamespaceHandler这个就是解析tx标签的类。
TxNamespaceHandler类,AnnotationDrivenBeanDefinitionParser就是标签的解析器,看AnnotationDrivenBeanDefinitionParser的parse解析方法,由于我们没有指定mode的模式,默认为proxy模式
打开AopAutoProxyConfigurer的configureAutoProxyCreator方法,注入了三个bean实例。
AnnotationTransactionAttributeSource(注解事物的属性类)
TransactionInterceptor(对代理方法进行拦截的处理类)
BeanFactoryTransactionAttributeSourceAdvisor(匹配是否对目标类进行切面)
这三个bean是事物的灵魂。整个事物就靠这三个类完成。那怎么把事物织入到bean中呢?
接下来我们看第一个红色框架方法,这里主要registerAutoProxyCreatorIfNecessary方法
注册了InfrastructureAdvisorAutoProxyCreator类。这个类干啥用呢?我们看看这个类的继承图,是不是看到了熟悉的beanPostProcessor接口
很多同志不明白就算你实现了beanPostProcessor接口又咋样?下面我用一张图来普及下bean的实例化过程;
看到红色描述没?bean在实例化后调用了实现beanPostProcessor接口的实例中postProcessAfterInitialization方法来对bean进行加强。前面我们提到的InfrastructureAdvisorAutoProxyCreator类正好实现了beanPostProcessor接口。那么在bean实例化完成后,通过实现beanPostProcessor接口的postProcessAfterInitialization方法就可以对bean进行事物加强了。我们发现InfrastructureAdvisorAutoProxyCreator并没有实现这个方法。咋回事呢。别急。这不是还实现了很多父类吗。我们父类找找。功夫不负有心人。在AbstractAutoProxyCreator这个父类我们发现了postProcessAfterInitialization的实现
接下来,我们看下wrapIfNecessary干了些什么事情?
1、如果处理过了,就不需要再处理了
2、如果需要处理的类是通知基础类,不需要再处理
3、获取匹配当前bean的增强器
4、如果bean增强器不为空,生成bean增强的代理类,返回代理类
5、如果bean增强器为空,直接返回目标bean
接下来继续看看怎么获取bean的增强器:
1.首先调用findEligibleAdvisors方法获取bean的增强器
2.findCandidateAdvisors方法获取所有注册的增强器的实例
3.findAdvisorsThatCanApply方法返回匹配当前bean的可用增强器实例
下面来分析下findCandidateAdvisors方法,其中又调用了findAdvisorBeans方法。从方法我们看出,从容器中寻找实现Advisor接口的所有实例,并添加到集合返回
回到最开始说过的注册事物三个类,其中BeanFactoryTransactionAttributeSourceAdvisor的继承关系图,哇喔。好巧哦。那就意味着BeanFactoryTransactionAttributeSourceAdvisor也会当做增强器返回。
既然已经返回了所有容器中的advice增强器。那接下来要做的事情是筛选出匹配当前bean的增强器,我们分析findAdvisorsThatCanApply方法
筛选过程如下
1、调用findAdvisorsThatCanApply方法,传入所有的增强器和当前bean的实例,
2、处理过IntroductionAdvisor增强器后,接下来调用canApply方法处理PointcutAdvisor增强器
3、由BeanFactoryTransactionAttributeSourceAdvisor继承图可以看到是BeanFactoryTransactionAttributeSourceAdvisor继承了PointcutAdvisor增强器,那么继续调用canApply方法的第一个入参pca.getPointcut()调用的是BeanFactoryTransactionAttributeSourceAdvisor中的getPointcut()方法返回
TransactionAttributeSourcePointcut实例。
4、获取当前bean的所有方法,循环调用TransactionAttributeSourcePointcut的matches方法进行匹配
查看TransactionAttributeSourcePointcut的matches方法
getTransactionAttributeSource调用的是BeanFactoryTransactionAttributeSourceAdvisor的getTransactionAttributeSource方法,到这里有人开始懵逼了。这个TransactionAttributeSource从哪里注入进来的??这得从头说起。还记得解析标签的注册了三个bean吗?
原来如此!相信不用我解释了吧,getTransactionAttributeSource返回的就是AnnotationTransactionAttributeSource,那么tas.getTransactionAttribute(method, targetClass)方法调用就是AnnotationTransactionAttributeSource的方法或者是其父类的方法,果不其然,在父类AbstractFallbackTransactionAttributeSource找到了getTransactionAttribute的实现方法
查询事物的属性过程:
1。查看方法是否有属性注解
2。查看方法坐在的类上面是否有属性注解
3。查看方法所在的接口上的方法上面是否有属性注解
4。查看方法所在的接口上面是否有属性注解
接下看下findTransactionAttribute方法,最终调用的SpringTransactionAnnotationParser的parseTransactionAnnotation解析方法,先获取方法上的配置的@Transactional注解的属性,然后封装成RuleBasedTransactionAttribute实例
到此,筛选工作完成,如果有bean的可用的增强器,就返回增强器数组。
接下就是为bean生成织入增强器。并生成增强事物后的代理类
接下看下createProxy创建到代理类的过程:
1.将拦截器封装为增强器
2.生成代理类
先解析所有的拦截器。调用wrap方法将拦截器封装成增强器
代理类生成流程,先创建代理工厂,接着创建代理类,创建代理类有两种模式,第一种是动态代理。第二种是cglib代理模式,默认是第一种
optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略,不推荐使用这个设置,目前这个属性仅用于CGLIB代理,对于JDK动态代理无效。
proxyTargetClass:属性为true时,目标类本身被代理而不是目标类的接口。如果这个属性值被设为true,CGLIB代理将被创建。
hasNOUserSuppliedProxyInterfaces:是否存在代理接口。
假设现在createAopProxy返回的是JdkDynamicAopProxy代理类,我们看到是通过Proxy来生成代理类,并且JdkDynamicAopProxy实现了InvocationHandler接口,重写了invoke方法。这里不做过多的描述,不懂的话,先度娘补习。
此时,我们已经生成了bean实例不再是原来初始化的bean了。而且带有铠甲(事物)功能的bean了。到了这里,可能还是很多小白很懵逼,生成的代理bean有啥用呢?我怎么样调用才能调用我的代理类中的方法呢?
欲知后事如何,请听下回分解!!!
- Spring事物(二)----基于注解源码分析之2
- 从源码分析 Spring 基于注解的事务
- Spring2.5源码解读 之 基于annotation的Controller实现原理分析(1)
- spring注解源码分析-解析和注入注解配置的资源
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- Dubbo源码分析(三):自定义Schema--基于Spring可扩展Schema提供自定义配置支持(spring配置文件中 配置标签支持)
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring源码分析之cache注解
- spring源码分析之事物
- springmvc工作原理以及源码分析(基于spring3.1.0)
- Spring对注解(Annotation)处理源码分析2——解析和注入注解配置的资源
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring 注解源码分析-扫描和读取bean定义
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring事物配置,声明式事务管理和基于@Transactional注解的使用
- spring源码分析之事物