<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      11.Java Spring框架源碼分析-事務-Spring事務源碼分析

      1. 開啟事務管理注解

      • @EnableTransactionManagement
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @Import(TransactionManagementConfigurationSelector.class)//導入了TransactionManagementConfigurationSelector
      public @interface EnableTransactionManagement {
      
      	boolean proxyTargetClass() default false;
      
      	AdviceMode mode() default AdviceMode.PROXY;
      
      	int order() default Ordered.LOWEST_PRECEDENCE;
      
      }
      

      這個注解向spring容器中導入了TransactionManagementConfigurationSelector,我們繼續研究

      2. TransactionManagementConfigurationSelector向容器導入AutoProxyRegistrar和ProxyTransactionManagementConfiguration

      • TransactionManagementConfigurationSelector.selectImports
      @Override
      protected String[] selectImports(AdviceMode adviceMode) {
      	//EnableTransactionManagement的mode參數,默認是PROXY
      	switch (adviceMode) {
      		case PROXY:
      			//導入AutoProxyRegistrar,ProxyTransactionManagementConfiguration
      			return new String[] {AutoProxyRegistrar.class.getName(),
      					ProxyTransactionManagementConfiguration.class.getName()};
      		case ASPECTJ:
      			return new String[] {
      					TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
      		default:
      			return null;
      	}
      }
      

      2.1. ImportSelector的selectImports是什么時候被調用的

      我們在TransactionManagementConfigurationSelector#selectImports打個斷點,調試調用棧如下:

      selectImports:45, TransactionManagementConfigurationSelector (org.springframework.transaction.annotation)
      selectImports:74, AdviceModeImportSelector (org.springframework.context.annotation)
      processImports:591, ConfigurationClassParser (org.springframework.context.annotation)
      doProcessConfigurationClass:304, ConfigurationClassParser (org.springframework.context.annotation)
      processConfigurationClass:247, ConfigurationClassParser (org.springframework.context.annotation)
      parse:200, ConfigurationClassParser (org.springframework.context.annotation)
      parse:169, ConfigurationClassParser (org.springframework.context.annotation)
      processConfigBeanDefinitions:308, ConfigurationClassPostProcessor (org.springframework.context.annotation)
      postProcessBeanDefinitionRegistry:228, ConfigurationClassPostProcessor (org.springframework.context.annotation)
      invokeBeanDefinitionRegistryPostProcessors:272, PostProcessorRegistrationDelegate (org.springframework.context.support)
      invokeBeanFactoryPostProcessors:92, PostProcessorRegistrationDelegate (org.springframework.context.support)
      invokeBeanFactoryPostProcessors:687, AbstractApplicationContext (org.springframework.context.support)
      refresh:524, AbstractApplicationContext (org.springframework.context.support)
      <init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
      main:48, DbConfig (com.zsk.transaction)
      

      1.給容器中注入AspectJAnnotationAutoProxyCreator組件.md.跟蹤ConfigurationClassProprocessor的postProcessBeanDefinitionRegistry方法一樣,也是在ConfigurationClassProprocessor的postProcessBeanDefinitionRegistry方法中進行處理

      • ConfigurationClassPostProcessor#processConfigBeanDefinitions
      public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
      	//...
      	do {
      	    //這里會調用ImportSelector的selectImports方法
      		parser.parse(candidates);
      		parser.validate();
      
      		Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
      		configClasses.removeAll(alreadyParsed);
      
      		// Read the model and create bean definitions based on its content
      		if (this.reader == null) {
      			this.reader = new ConfigurationClassBeanDefinitionReader(
      					registry, this.sourceExtractor, this.resourceLoader, this.environment,
      					this.importBeanNameGenerator, parser.getImportRegistry());
      		}
      		//這里會調用ImportBeanDefinitionRegistrar的registerBeanDefinitions方法
      		this.reader.loadBeanDefinitions(configClasses);
      		//...
      }
      

      3. 先研究AutoProxyRegistrar

      3.1. 向容器中注冊InfrastructureAdvisorAutoProxyCreator:用于創建代理對象

      3.1.1. 類圖


      InfrastructureAdvisorAutoProxyCreator是spring aop 的核心,參考1.給容器中注入AspectJAnnotationAutoProxyCreator組件.md

      • registerBeanDefinitions
      public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
      	boolean candidateFound = false;
      	Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
      	for (String annType : annTypes) {
      		AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
      		if (candidate == null) {
      			continue;
      		}
      		//獲取EnableTransactionManagement中的mode和proxyTartgetClass屬性
      		Object mode = candidate.get("mode");
      		Object proxyTargetClass = candidate.get("proxyTargetClass");
      		if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
      				Boolean.class == proxyTargetClass.getClass()) {
      			candidateFound = true;
      			//mode屬性是PROXY
      			if (mode == AdviceMode.PROXY) {
      				//調用
      				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
      				//如果proxyTargetClass屬性是true
      				if ((Boolean) proxyTargetClass) {
      					//轉調這個
      					AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
      					return;
      				}
      			}
      		}
      	}
      	if (!candidateFound && logger.isWarnEnabled()) {
      		String name = getClass().getSimpleName();
      		logger.warn(String.format("%s was imported but no annotations were found " +
      				"having both 'mode' and 'proxyTargetClass' attributes of type " +
      				"AdviceMode and boolean respectively. This means that auto proxy " +
      				"creator registration and configuration may not have occurred as " +
      				"intended, and components may not be proxied as expected. Check to " +
      				"ensure that %s has been @Import'ed on the same class where these " +
      				"annotations are declared; otherwise remove the import of %s " +
      				"altogether.", name, name, name));
      	}
      }
      
      • registerAutoProxyCreatorIfNecessary
      public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
      	return registerAutoProxyCreatorIfNecessary(registry, null);
      }
      	
      public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
      	//給容器中注冊一個InfrastructureAdvisorAutoProxyCreator組件,這玩意也是個SmartInstantiationAwareBeanPostProcessor。
      	//本質上都是利用后置處理器在對象創建之后包裝對象,返回一個代理對象(增強器)。代理對象執行方法利用攔截器鏈進行
      	return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
      }
      
      private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
      	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
      
      	if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      		BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
      			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
      			int requiredPriority = findPriorityForClass(cls);
      			if (currentPriority < requiredPriority) {
      				apcDefinition.setBeanClassName(cls.getName());
      			}
      		}
      		return null;
      	}
      
      	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
      	beanDefinition.setSource(source);
      	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
      	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
      	return beanDefinition;
      }
      

      4. 然后研究ProxyTransactionManagementConfiguration

      @Configuration//一個配置類,注入了bean
      public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
      
      	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
      	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
      		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
      		advisor.setTransactionAttributeSource(transactionAttributeSource());//設置解析@Transactional屬性的類
      		advisor.setAdvice(transactionInterceptor());//設置事務攔截器
      		advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
      		return advisor;
      	}
      
      	@Bean
      	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      	public TransactionAttributeSource transactionAttributeSource() {
      		//用來解析@Transactional里面的屬性
      		return new AnnotationTransactionAttributeSource();
      	}
      
      	@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;
      	}
      
      }
      

      這個Configuration向容器中注冊了一個@BeanBeanFactoryTransactionAttributeSourceAdvisor ,這個Bean包含了兩個bean

      • TransactionAttributeSource用于解析@Transactional里面的屬性
      • TransactionInterceptor事務攔截器

      4.1. 創建用于解析@Transactional里面的屬性的bean:AnnotationTransactionAttributeSource

      • AnnotationTransactionAttributeSource構造方法
      public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
      		this.publicMethodsOnly = publicMethodsOnly;
      		this.annotationParsers = new LinkedHashSet<TransactionAnnotationParser>(4);
      		//利用注解解析器解析SpringTransactionAnnotation、JtaTransactionAnnotation、Ejb3TransactionAnnotation
      		this.annotationParsers.add(new SpringTransactionAnnotationParser());
      		if (jta12Present) {
      			this.annotationParsers.add(new JtaTransactionAnnotationParser());
      		}
      		if (ejb3Present) {
      			this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
      		}
      	}
      

      4.1.1. 如何解析的

      • SpringTransactionAnnotationParser parseTransactionAnnotation
      protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
      		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
      
      		//解析@Transactional里面的各種屬性
      		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"));
      
      		List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
      		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
      			rollbackRules.add(new RollbackRuleAttribute(rbRule));
      		}
      		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
      			rollbackRules.add(new RollbackRuleAttribute(rbRule));
      		}
      		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
      			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
      		}
      		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
      			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
      		}
      		rbta.setRollbackRules(rollbackRules);
      
      		return rbta;
      	}
      
      

      4.2. 創建用于攔截事務的bean:TransactionInterceptor

      是一個MethodInterceptor,在目標方法執行前調用

      4.2.1. 事務攔截器的調用

      • invoke
      public Object invoke(final MethodInvocation invocation) throws Throwable {
      		// Work out the target class: may be {@code null}.
      		// The TransactionAttributeSource should be passed the target class
      		// as well as the method, which may be from an interface.
      		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
      
      		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
      		return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
      			@Override
      			public Object proceedWithInvocation() throws Throwable {
      				return invocation.proceed();
      			}
      		});
      	}
      
      4.2.1.1. 事務的創建、提交/回滾
      • TransactionAspectSupport invokeWithinTransaction
      protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
      		throws Throwable {
      
      	// If the transaction attribute is null, the method is non-transactional.
      	//獲取事務屬性
      	final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
      	//獲取PlatformTransactionManager
      	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
      	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
      
      	if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      		// Standard transaction demarcation with getTransaction and commit/rollback calls.
      		//創建事務
      		TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      
      		Object retVal;
      		try {
      			// This is an around advice: Invoke the next interceptor in the chain.
      			// This will normally result in a target object being invoked.
      			//執行目標方法
      			retVal = invocation.proceedWithInvocation();
      		}
      		//如果出現了異常
      		catch (Throwable ex) {
      			// target invocation exception
      			//使用事務管理器進行回滾
      			completeTransactionAfterThrowing(txInfo, ex);
      			throw ex;
      		}
      		finally {
      			cleanupTransactionInfo(txInfo);
      		}
      		//沒有異常,那么使用事務管理器提交事務
      		commitTransactionAfterReturning(txInfo);
      		return retVal;
      	}
      
      	else {
      		final ThrowableHolder throwableHolder = new ThrowableHolder();
      
      		// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
      		try {
      			Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
      					new TransactionCallback<Object>() {
      						@Override
      						public Object doInTransaction(TransactionStatus status) {
      							TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
      							try {
      								
      								return invocation.proceedWithInvocation();
      							}
      							
      							catch (Throwable ex) {
      								if (txAttr.rollbackOn(ex)) {
      									// A RuntimeException: will lead to a rollback.
      									if (ex instanceof RuntimeException) {
      										throw (RuntimeException) ex;
      									}
      									else {
      										throw new ThrowableHolderException(ex);
      									}
      								}
      								else {
      									// A normal return value: will lead to a commit.
      									throwableHolder.throwable = ex;
      									return null;
      								}
      							}
      							finally {
      								cleanupTransactionInfo(txInfo);
      							}
      						}
      					});
      
      			// Check result state: It might indicate a Throwable to rethrow.
      			if (throwableHolder.throwable != null) {
      				throw throwableHolder.throwable;
      			}
      			return result;
      		}
      		catch (ThrowableHolderException ex) {
      			throw ex.getCause();
      		}
      		catch (TransactionSystemException ex2) {
      			if (throwableHolder.throwable != null) {
      				logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
      				ex2.initApplicationException(throwableHolder.throwable);
      			}
      			throw ex2;
      		}
      		catch (Throwable ex2) {
      			if (throwableHolder.throwable != null) {
      				logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
      			}
      			throw ex2;
      		}
      	}
      }
      
      4.2.1.1.1. 判斷使用事務管理器
      • determineTransactionManager
      protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
      	// Do not attempt to lookup tx manager if no tx attributes are set
      	if (txAttr == null || this.beanFactory == null) {
      		return getTransactionManager();
      	}
      
      	String qualifier = txAttr.getQualifier();
      	//注解上有指定那么使用指定的TransactionManager
      	if (StringUtils.hasText(qualifier)) {
      		return determineQualifiedTransactionManager(qualifier);
      	}
      	else if (StringUtils.hasText(this.transactionManagerBeanName)) {
      		return determineQualifiedTransactionManager(this.transactionManagerBeanName);
      	}
      	//使用默認的TransactionManager
      	else {
      		PlatformTransactionManager defaultTransactionManager = getTransactionManager();
      		if (defaultTransactionManager == null) {
      			defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
      			if (defaultTransactionManager == null) {
      				//其實就是從容器中獲取PlatformTransactionManager bean
      				defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
      				this.transactionManagerCache.putIfAbsent(
      						DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
      			}
      		}
      		return defaultTransactionManager;
      	}
      }
      
      posted @ 2025-07-05 10:29  ThinkerQAQ  閱讀(15)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 中文字幕一区二区网站| 东莞市| 精品一区二区三区在线观看l| 色婷婷综合久久久久中文一区二区| 国产精品中文字幕综合| 人妻无码久久精品| 亚洲欧美日韩国产精品专区| 2020国产欧洲精品网站| 我国产码在线观看av哈哈哈网站| 日韩一区二区三区高清视频| 中文有无人妻vs无码人妻激烈| 久久妇女高潮喷水多| 国产精品天天看天天狠| 成人免费看片又大又黄| 亚洲天堂一区二区成人在线| 亚洲精品国产中文字幕| 国产午夜精品久久精品电影| 国产成人精品亚洲精品密奴| 色国产视频| 亚洲AV高清一区二区三区尤物| 亚洲午夜无码久久久久蜜臀av| 亚洲人成电影在线天堂色| 国产一区在线观看不卡| 亚洲最大成人av在线天堂网| 亚洲红杏AV无码专区首页| 无码伊人66久久大杳蕉网站谷歌 | 精品国产午夜福利伦理片| 无码av波多野结衣| 8050午夜二级无码中文字幕| 久久精品国产99精品亚洲| 国产精品亚洲mnbav网站| 久久人人97超碰精品| 精品中文人妻在线不卡| 成人网站免费观看永久视频下载 | 亚洲日本va午夜中文字幕久久 | 人妻丝袜中文无码AV影音先锋专区| 97久久综合亚洲色hezyo| 免费无码一区无码东京热| 亚洲AV成人片不卡无码| 中文字幕av中文字无码亚 | 日韩伦理片一区二区三区|