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; //省略。。。。。。 } } |