过年前项目不是那么忙了,利用这段时间看看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就满足被增强的条件,会放入缓存,保存这个方法相关的隔离级别和传播特性等事务属性。当找到了合适的增强器后,使用动态代理对目标类的目标方法做增强。
这样事务的初始化就完成了