1. 程式人生 > >Spring原始碼解析---事務解析

Spring原始碼解析---事務解析

 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;

                            //省略。。。。。。

                   }

         }