Spring 事務源碼分析
1.分析EnableTransactionManagement
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default Ordered.LOWEST_PRECEDENCE; } |
我們分析TransactionManagementConfigurationSelector,如下表格,是以通過ImportSelector接口的selectImports()方法傳回要注冊到容器中的的元件。
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {} public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {} |
那麼它注冊了哪些元件那:
protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME}; default: return null; } } |
我們從EnableTransactionManagement的AdviceMode mode() default AdviceMode.PROXY;中看出,注冊兩個元件AutoProxyRegistrar,ProxyTransactionManagementConfiguration。
①AutoProxyRegistrar,
向容器中注冊了AutoProxyCreator即InfrastructureAdvisorAutoProxyCreator(增強自動代理建立器)這個元件。InfrastructureAdvisorAutoProxyCreator利用後置處理器機制,在對象建立以後,包裝對象,傳回代理對象。通過攔截器鍊對代理對象執行方法進行調用。
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //隻給出關鍵代碼 Object proxyTargetClass = candidate.get("proxyTargetClass"); if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) { candidateFound = true; if (mode == AdviceMode.PROXY) {//預設值就是PROXY AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); if ((Boolean) proxyTargetClass) {//預設值是false 看EnableTransactionManagement注解 AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); return; } } } } } @Nullable public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAutoProxyCreatorIfNecessary(registry, null); } @Nullable public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); } |
②ProxyTransactionManagementConfiguration
給容器中注冊事務增強器。在注冊的時候需要事務屬性
advisor.setTransactionAttributeSource(transactionAttributeSource());
同時也加入了事務攔截器advisor.setAdvice(transactionInterceptor());
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();//事務屬性 advisor.setTransactionAttributeSource(transactionAttributeSource()); advisor.setAdvice(transactionInterceptor()); if (this.enableTx != null) { advisor.setOrder(this.enableTx.<Integer>getNumber("order")); } return advisor; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } |
注冊Spring注解解析器,jta事務注解解析器,Ejb事務注解解析器
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) { this.publicMethodsOnly = publicMethodsOnly; this.annotationParsers = new LinkedHashSet<>(2); this.annotationParsers.add(new SpringTransactionAnnotationParser()); if (jta12Present) { this.annotationParsers.add(new JtaTransactionAnnotationParser()); } if (ejb3Present) { this.annotationParsers.add(new Ejb3TransactionAnnotationParser()); } } |
spring事務注解解析器,會解析我們@Transactional中定義的屬性
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable { //隻給出關鍵代碼 protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) { RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); Propagation propagation = attributes.getEnum("propagation"); rbta.setPropagationBehavior(propagation.value()); Isolation isolation = attributes.getEnum("isolation"); rbta.setIsolationLevel(isolation.value()); rbta.setTimeout(attributes.getNumber("timeout").intValue()); rbta.setReadOnly(attributes.getBoolean("readOnly")); rbta.setQualifier(attributes.getString("value")); ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>(); Class<?>[] rbf = attributes.getClassArray("rollbackFor"); for (Class<?> rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName"); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } Class<?>[] nrbf = attributes.getClassArray("noRollbackFor"); for (Class<?> rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName"); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; } } |
另一方面添加了事務攔截器:建立了一個TransactionInterceptor,它儲存了事務屬性資訊,事務管理器。
@Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) { interceptor.setTransactionManager(this.txManager); } return interceptor; } |
它是一個方法攔截器,我們在容器中存放着代理對象,代理對象要執行方法法了,那麼攔截器就會攔截進行工作。
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable { public Object invoke(final MethodInvocation invocation) throws Throwable { Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); } } |
攔截到執行的方法,首先獲得事務屬性,然後獲得事務處理器,根據事務配置判斷是否建立事務,執行目标方法,若執行過程中出現異常,那麼調用事務管理器復原,否則調用事務管理器送出事務
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable { //先獲得事務屬性 TransactionAttributeSource tas = getTransactionAttributeSource(); final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null); //然後獲得事務管理器,預設從容器中擷取bean類型為PlatformTransactionManager的事務管理器,若制定了事務管理器,那麼就傳回制定的事務管理器 final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { //若有必要那麼建立事務 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; //先執行目标方法 try { retVal = invocation.proceedWithInvocation(); } //若事務出現異常,那麼txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());事務復原 catch (Throwable ex) { completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } //若正常應用事務管理器送出事務 commitTransactionAfterReturning(txInfo); return retVal; //省略。。。。。。 } } |