过年前项目不是那么忙了,利用这段时间看看spring的事务处理的源码,现在总结如下
1 本篇为初始化篇,通俗的说就是所谓的事务管理,在spring启动的时候,该对某些方法做事务增强就已经确定好了。本篇就是要分析这部分源码
2 下一篇为分析执行部分,尤其是针对require require_new这种需要挂起当前事务的传播特性spring源码是怎么写的
进入主题:
1 要使用声明式事务就要在spring的配置文件里写注解
<tx:annotation-driven> 注意到 命令空间 tx 所以我们找到了对此命令空间的解析类 TxNamespaceHandler
2 在 TxNamespaceHandler中会发现.
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());继续分析AnnotationDrivenBeanDefinitionParser。
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
registerTransactionAspect(element, parserContext);
}
else {
// mode="proxy"
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
继续看 AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); 干了什么
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// Create the TransactionAttributeSource definition.
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// Create the TransactionInterceptor definition.
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registerTransactionManager(element, interceptorDef);
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the TransactionAttributeSourceAdvisor definition.
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
该方法的作用就是初始化一个类 该类为InfrastructureAdvisorAutoProxyCreator。
该类最重要的属性就是实现了BeanPostProcessor。
简单说说BeanPostProcessor的作用。BeanPostProcessor接口有个方法postProcessAfterInitialization,实现该方法就会对一个java bean初始化的时候做一个增强。
没错,我们在使用spring做事务控制的时候,都会写一个Service接口 并写ServiceImpl实现类,其实这个实现类就已经不是我们当初写的了,而是经过了BeanPostProcessor的增强。
除了这个InfrastructureAdvisorAutoProxyCreator初始化还有三个Bean,分别是
AnnotationTransactionAttributeSource,TransactionInterceptor,
BeanFactoryTransactionAttributeSourceAdvisor。这三个Bean关系是这样的。
AnnotationTransactionAttributeSource和 TransactionInterceptor作为属性注入到 BeanFactoryTransactionAttributeSourceAdvisor。
简单的说下这三个bean的作用,可以有一个感性认识:
BeanFactoryTransactionAttributeSourceAdvisor -- 是一个advisor也就是增强器,这样在PostBeanProcessor处理的时候 该advisor会被选出来
AnnotationTransactionAttributeSource -- 包装了方法的事务属性,比如某个方法的隔离级别 传播特性 回滚配置
TransactionInterceptor -- 干具体事的,这里面的方法就是对目标方法增强的具体实现。开启事务,回滚或者提交下面详细看一下PostBeanProcessor是怎么执行的
顺着PostBeanProcessor对ServiceImp做增强的思路,接下来就是看看这个增强是怎么做的
AbstractAutoProxyCreator.postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
这部分的实现很清晰:1 找增强器 2 根据增强器对目标bean增强
其中 找增强器的过程就是把该bean通过class反射机制遍历其中的method,只要有一个method上有注解@Transactional 。该bean就满足被增强的条件,会放入缓存,保存这个方法相关的隔离级别和传播特性等事务属性。当找到了合适的增强器后,使用动态代理对目标类的目标方法做增强。
这样事务的初始化就完成了