吃透Spring事务机制

解析自定义标签

Spring通过注解开启事务的XML配置

	<context:property-placeholder location="classpath:META-INF/jdbc.properties" />

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${dev.driver}" />
		<property name="url" value="${dev.url}" />
		<property name="username" value="${dev.username}" />
		<property name="password" value="${dev.password}" />
	</bean>

	<bean id="deptService" class="com.demo.tx.DeptServiceImpl">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager"/>

Spring解析自定义标签< tx>的过程

Spring中AOP应用原理一节中提到过关于自定义标签的解析过程,与解析< aop >标签过程一样,通过TxNameSpaceHandler去调用AnnotationDrivenBeanDefinitionParser去解析<tx:annotation-driven transaction-manager=“transactionManager”/>,在解析的过程中与之前解析<aop:aspectj-autoproxy />不同的地方在于,除了向BeanFactory中添加一个实现了接口BeanPostProcessor的类InfrastructureAdvisorAutoProxyCreator的BeanDefinition外,还添加了三个其他的类的BeanDefinition:

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
   
			// create the InfrastructureAdvisorAutoProxyCreator definition
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
   
				Object eleSource = parserContext.extractSource(element);

				// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(
						"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				registerTransactionManager(element, interceptorDef);
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

				// Create the TransactionAttributeSourceAdvisor definition.
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
   
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

				CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
				compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
				parserContext.registerComponent(compositeDef);
			}
		}

InfrastructureAdvisorAutoProxyCreator是一个很普通的类,除了实现BeanPostProcessor之外,还实现了BeanFactoryAware接口,BeanFactoryAware也只有一个方法setBeanFactory用于在初始化是自动设置beanFacoty属性。setBeanFactory是在bean初始化的过程中,在AbstractAutowireCapableBeanFactory的
invokeAwareMethods方法中进行设值。

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
   

	private ConfigurableListableBeanFactory beanFactory;


	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   
		super.initBeanFactory(beanFactory);
		this.beanFactory = beanFactory;
	}

	@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
   
		return (this.beanFactory.containsBeanDefinition(beanName) &&
				this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
	}

}
private void invokeAwareMethods(final String beanName, final Object bean) {
   
		if (bean instanceof Aware) {
   
			if (bean instanceof BeanNameAware) {
   
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
   
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
   
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor和AnnotationTransactionAttributeSource三者的类关系图:
在这里插入图片描述
BeanFactoryTransactionAttributeSourceAdvisor类图
在这里插入图片描述

获取bean对应的事务增强器

在上一节的AOP中说过,在bean的初始化过程完成以后,会对调用BeanPostPorcessor对bean进行后置处理,其过程就是获取bean的Advisor,使用动态代理创建代理对象。回顾上一章节中,在调用AnnotationAwareAspectJAutoProxyCreator获取增强器时,会获取父类的增强器:

protected List<Advisor> findCandidateAdvisors() {
   
		// Add all the Spring advisors found according to superclass rules.
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		return advisors;
	}

看一下父类AbstractAdvisorAutoProxyCreator的findCandidateAdvisors方法,只有一段简单的代码:

protected List<Advisor> findCandidateAdvisors() {
   
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

跟着源码执行过程找到BeanFactoryAdvisorRetrievalHelper的方法,这个方法主要步骤:
1、找到所有类型为Advisor的beanNames,进行缓存;
2、判断缓存中是否有Advisor;
3、遍历beanNames,生成bean。

public List<Advisor> findAdvisorBeans() {
   
		// Determine list of advisor bean names, if not cached already.
		String[] advisorNames = null;
		synchronized (this) {
   
			advisorNames = this.cachedAdvisorBeanNames;
			if (advisorNames == null) {
   
				// Do not initialize FactoryBeans here: We need to leave all regular beans
				// uninitialized to let the auto-proxy creator apply to them!
				advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Advisor.class, true, false);
				this.cachedAdvisorBeanNames = advisorNames;
			}
		}
		if (advisorNames.length == 0) {
   
			return new LinkedList<Advisor>();
		}

		List<Advisor> advisors = new LinkedList<Advisor>();
		for (String name : advisorNames) {
   
			if (isEligibleBean(name)) {
   
				if (this.beanFactory.isCurrentlyInCreation(name)) {
   
					if (logger.isDebugEnabled()) {
   
						logger.debug("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
   
					try {
   
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
   
						Throwable rootCause = ex.getMostSpecificCause();
						if (rootCause instanceof BeanCurrentlyInCreationException) {
   
							BeanCreationException bce = (BeanCreationException) rootCause;
							if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
   
								if (logger.isDebugEnabled()) {
   
									logger.debug("Skipping advisor '" + name +
											"' with dependency on currently created bean: " + ex.getMessage());
								}
								// Ignore: indicates a reference back to the bean we're trying to advise.
								// We want to find advisors other than the currently created bean itself.
								continue;
							}
						}
						throw ex;
					}
				}
			}
		}
		return advisors;
	}

从集合中挑选出可以作用于bean的增强器

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   
		if (candidateAdvisors.isEmpty()) {
   
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
		// 首先处理引介增强器
		for (Advisor candidate : candidateAdvisors) {
   
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
   
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		
		for (Advisor candidate : candidateAdvisors) {
   
			if (candidate instanceof IntroductionAdvisor) {
   
				// already processed
				continue;
			}
			// BeanFactoryTransactionAttributeSourceAdvisor
			if (canApply(candidate, clazz, hasIntroductions)) {
   
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}

BeanFactoryTransactionAttributeSourceAdvisor是否可以作用于bean的步骤:
1、判断BeanFactoryTransactionAttributeSourceAdvisor是一个PointcutAdvisor,获取PointcutAdvisor的切点Pointcut,是一个TransactionAttributeSourcePointcut内部类;

2、通过TransactionAttributeSourcePointcut获取匹配器MethodMatcher,TransactionAttributeSourcePointcut实现了MethodMatcher接口,此处获取的MethodMatcher还是TransactionAttributeSourcePointcut;
3、通过matches方法判断类中的方法上是否有@Transactional注解,在判断类上是否存在@Transactional注解。

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
   
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
   
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
   
			Method[] methods = clazz.getMethods();
			for (Method method : methods) {
   
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值