Spring事务源码(二)

Spring事务源码(二)

一、我们从@EnableTransactionManagement注解开始分析
在这里插入图片描述

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    
    

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJTransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
		/** * 往容器中添加组件 
		1) AutoProxyRegistrar 
		 2) ProxyTransactionManagementConfiguration
		* */
	@Override
	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;
		}
	}

}

AutoProxyRegistrar

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
		boolean candidateFound = false;
		//从我们传入进去的配置类上获取所有的注解的
		Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
		//循环我们上一步获取的注解
		for (String annoType : annoTypes) {
    
    
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
			if (candidate == null) {
    
    
				continue;
			}
			//获取注解的mode属性
			Object mode = candidate.get("mode");
			//获取注解的proxyTargetClass
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			//根据mode和proxyTargetClass的判断来注册不同的组件
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
    
    
				candidateFound = true;
				if (mode == AdviceMode.PROXY) {
    
    
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					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));
		}
	}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    
    
		return registerAutoProxyCreatorIfNecessary(registry, null);
	}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
    
    
		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
    
    
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

	//判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator名字的bean定义,
		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;
		}
		//自己注册一个org.springframework.aop.config.internalAutoProxyCreator的组件
		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;
	}

在这里插入图片描述
实现了我们的接口 InstantiationAwareBeanPostProcessor类型的后置处理器,为我们容器中做了 什么事情
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    
    
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
    
    
			if (this.advisedBeans.containsKey(cacheKey)) {
    
    
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
    
    
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		if (beanName != null) {
    
    
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
			if (targetSource != null) {
    
    
				this.targetSourcedBeans.add(beanName);
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) {
    
    
		return true;
	}

:实现了我们的接口BeanPostProcessor类型的后置处理器,为我们容器中做了什么事情

@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
    
    
		return bean;
	}

	/**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@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;
	}

TransactionManagementConfigurationSelector 为我们还导入了一个类 ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
    

	/** 
	* 为我我们容器中导入了 beanName为org.springframework.transaction.config.internalTransactionAdvisor 
	* * 类型为:BeanFactoryTransactionAttributeSourceAdvisor 的增强器
	 *
	* */
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
    
    
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		//设置了事物源属性对象
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		//设置了事物拦截器对象
		advisor.setAdvice(transactionInterceptor());
		advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		return advisor;
	}
	
	/** * 定义了一个事物属性源对象 * */
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
    
    
		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;
	}

}

在这里插入图片描述
在这里插入图片描述
二、结束,本章主要介绍了@EnableTransactionManagement注解为我们容器放了那些东西,下一章将在此基础上分析源码。

猜你喜欢

转载自blog.csdn.net/mlplds/article/details/103300190