Spring事务是我们日常工作中经常使用的一项技术,Spring提供了编程、注解、aop切面三种方式供我们使用Spring事务,其中编程式事务因为对代码入侵较大所以不被推荐使用,注解和aop切面的方式可以基于需求自行选择,我们以注解的方式为例来分析Spring事务的原理和源码实现。
首先我们简单看一下Spring事务的使用方式,配置:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
在需要开启事务的方法上加上@Transactional注解即可,这里需要注意的是,当
标签在不指定transaction-manager属性的时候,会默认寻找id固定名为transactionManager的bean作为事务管理器,如果没有id为transactionManager的bean并且在使用@Transactional注解时也没有指定value(事务管理器),程序就会报错。当我们在配置两个以上的
标签时,如下:
<tx:annotation-driven transaction-manager="transactionManager1"/>
<bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager2"/>
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource2"/>
bean>
这时第一个
会生效,也就是当我们使用@Transactional注解时不指定事务管理器,默认使用的事务管理器是transactionManager1,后文分析源码时会具体提到这些注意点。
下面我们开始分析相关源码,首先看一下对
标签的解析,这里需要读者对Spring自定义标签解析的过程有一定的了解,详见Spring源码解析之自定义标签的解析。锁定TxNamespaceHandler:
public void init() {
// 对 标签的解析
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
// 对 标签的解析
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
// 对JTA的支持
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
我们来看我们关心的
标签的解析:
AnnotationDrivenBeanDefinitionParser:
public BeanDefinition parse(Element element, ParserContext parserContext) {
registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// 提供对aspectj方式进行事务切入的支持
registerTransactionAspect(element, parserContext);
}
else {
/* 配置自动代理创建器 */
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer:
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
/* 注册自动代理创建器 */
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// 创建AnnotationTransactionAttributeSource的BeanDefinition
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// 创建TransactionInterceptor的BeanDefinition
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
/* 注册事务管理器 */
registerTransactionManager(element, interceptorDef);
// 为TransactionInterceptor织入AnnotationTransactionAttributeSource
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// 创建BeanFactoryTransactionAttributeSourceAdvisor的BeanDefinition
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 为BeanFactoryTransactionAttributeSourceAdvisor织入AnnotationTransactionAttributeSource
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 为BeanFactoryTransactionAttributeSourceAdvisor织入TransactionInterceptor
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);
}
}
这个方法比较长,关键的部分做了注释,最外围的if判断限制了
标签只能被解析一次,所以只有第一次被解析的标签会生效。接下来分别注册了三个BeanDefinition,分别为AnnotationTransactionAttributeSource、TransactionInterceptor和BeanFactoryTransactionAttributeSourceAdvisor,将第一个BeanDefinition添加到了第二个BeanDefinition的属性中,然后将前两个BeanDefinition添加到第三个BeanDefinition的属性当中,这三个bean支撑了整个事务功能,后面会详细说明。我们先来看事务管理器的注册:
AnnotationDrivenBeanDefinitionParser:
private static void registerTransactionManager(Element element, BeanDefinition def) {
/* 添加事务管理器的beanName */
def.getPropertyValues().add("transactionManagerBeanName",
TxNamespaceHandler.getTransactionManagerName(element));
}
TxNamespaceHandler:
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
static String getTransactionManagerName(Element element) {
return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
}
还记得当
标签在不指定transaction-manager属性的时候,会默认寻找id固定名为transactionManager的bean作为事务管理器这个注意事项么,就是在这里实现的。下面我们来看自动代理创建器的注册:
AopNamespaceUtils:
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
/* 注册InfrastructureAdvisorAutoProxyCreator */
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
// 设置proxy-target-class和expose-proxy配置
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
AopConfigUtils:
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
注册代理创建器的过程我们在分析Spring AOP源码的文章中已经分析过,这里不再赘述,Spring事务和AOP有很大的关联,建议读者在阅读本篇文章之前先看一下笔者关于Spring AOP源码分析的文章,详见:Spring AOP源码解析之配置解析篇。
注册InfrastructureAdvisorAutoProxyCreator这个bean的目的是什么呢?我们看下这个类的层次:
我们发现这个类间接实现了BeanPostProcessor接口,我们知道,Spring会保证所有bean在实例化的时候都会调用其postProcessAfterInitialization方法,我们可以使用这个方法包装和改变bean,而真正实现这个方法是在其父类AbstractAutoProxyCreator类中:
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;
}
AbstractAutoProxyCreator:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean; // 如果已经处理过,直接返回
}
// 如果是aop的基础类不需要代理,或者配置了bean不需要代理,直接返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/* 获取bean匹配的增强器 */
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
/* 创建代理 */
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
AbstractAdvisorAutoProxyCreator:
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
/* 寻找合适的增强器 */
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
AbstractAdvisorAutoProxyCreator:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
/* 获取所有候选增强器 */
List<Advisor> candidateAdvisors = findCandidateAdvisors();
/* 获取可用的增强器 */
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
AnnotationAwareAspectJAutoProxyCreator:
protected List<Advisor> findCandidateAdvisors() {
/* 获取父类中的其他aop配置声明 */
List<Advisor> advisors = super.findCandidateAdvisors();
/* 获取注解方式配置的aop信息 */
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
AbstractAdvisorAutoProxyCreator:
protected List<Advisor> findCandidateAdvisors() {
/* 获取增强器bean */
return this.advisorRetrievalHelper.findAdvisorBeans();
}
BeanFactoryAdvisorRetrievalHelper:
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 获取所有Advisor类型的bean的名称
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 {
// 创建bean并添加到增强器集合中返回
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());
}
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
上面这个方法相信大家已经看出了它的目的,先找出所有对应Advisor的类的beanName,再通过beanFactory.getBean方法获取这些bean并返回。不知道大家还是否记得在文章开始的时候提到的三个类,其中BeanFactoryTransactionAttributeSourceAdvisor实现了Advisor接口,所以这个bean就会在此被提取出来,而另外两个bean被织入了BeanFactoryTransactionAttributeSourceAdvisor当中,所以也会一起被提取出来,下图为BeanFactoryTransactionAttributeSourceAdvisor类的层次:
我们发现它实现了PointcutAdvisor接口,后面会用到。下面让我们来看Spring如何在所有候选的增强器中获取匹配的增强器:
AbstractAdvisorAutoProxyCreator:
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
/* 匹配适用于当前bean的增强器 */
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
AopUtils:
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) {
/* 判断当前增强是否可以应用在当前bean上 */
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
// 引介增强已经处理过了,无需再次处理
if (candidate instanceof IntroductionAdvisor) {
continue;
}
/* 判断当前增强是否可以应用在当前bean上 */
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
上面的方法中提到引介增强的概念,我们在Spring AOP源码分析的文章中已经解释过,不再赘述。另外这个方法用两个重载的canApply方法为目标类寻找匹配的增强器,其中第一个canApply方法会调用第二个canApply方法并将第三个参数传为false:
AopUtils:
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
// 判断引介增强是否匹配
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
/* 判断当前增强是否可以应用在当前bean上 */
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
return true;
}
}
在上面BeanFactoryTransactionAttributeSourceAdvisor类的层次中我们看到它实现了PointcutAdvisor接口,所以会调用第二个条件分支判断中的canApply方法进行判断,第一个参数pca.getPointcut()也就是调用BeanFactoryTransactionAttributeSourceAdvisor的getPointcut方法:
public Pointcut getPointcut() {
return this.pointcut;
}
BeanFactoryTransactionAttributeSourceAdvisor:
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
这里的transactionAttributeSource也就是我们在文章开始看到的为BeanFactoryTransactionAttributeSourceAdvisor织入的两个bean中的AnnotationTransactionAttributeSource,我们以TransactionAttributeSourcePointcut作为第一个参数继续跟踪canApply方法:
AopUtils:
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();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
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 = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
/* 匹配判断 */
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
我们跟踪pc.getMethodMatcher()方法也就是TransactionAttributeSourcePointcut的getMethodMatcher方法是在它的父类中实现:
StaticMethodMatcherPointcut:
public final MethodMatcher getMethodMatcher() {
return this;
}
发现方法直接返回this,也就是下面methodMatcher.matches方法就是调用TransactionAttributeSourcePointcut的matches方法:
public boolean matches(Method method, Class<?> targetClass) {
if (TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
/* 解析事务属性配置,判断是否为null */
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
在上面我们看到其实这个tas就是AnnotationTransactionAttributeSource,这里的目的其实也就是判断我们的业务方法或者类上是否有@Transactional注解,跟踪AnnotationTransactionAttributeSource的getTransactionAttribute方法:
AbstractFallbackTransactionAttributeSource:
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
Object cacheKey = getCacheKey(method, targetClass);
Object cached = this.attributeCache.get(cacheKey);
if (cached != null) {
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return (TransactionAttribute) cached;
}
}
else {
/* 获取事务属性 */
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isDebugEnabled()) {
logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
// 将解析好的事务属性存入缓存
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
AbstractFallbackTransactionAttributeSource:
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
Class<?> userClass = ClassUtils.getUserClass(targetClass);
// method为接口中的方法,specificMethod为具体类中的方法
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
/* 查看方法中是否存在事务声明 */
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
/* 查看方法所在类中是否存在事务声明 */
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
/* 查看接口方法中是否存在事务声明 */
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
/* 查看接口类中是否存在事务声明 */
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
方法中的事务声明优先级最高,如果方法上没有声明则在类上寻找:
AnnotationTransactionAttributeSource:
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
AnnotationTransactionAttributeSource:
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
AnnotationTransactionAttributeSource:
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
if (ae.getAnnotations().length > 0) {
/* 遍历事务注解解析器 */
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
/* 解析事务注解 */
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
return attr;
}
}
}
return null;
}
this.annotationParsers是在AnnotationTransactionAttributeSource类初始化的时候初始化的:
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet<TransactionAnnotationParser>(2);
// 添加Spring事务注解解析器
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) { // 对JTA的支持
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) { // 对EJB的支持
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
所以annotationParser.parseTransactionAnnotation就是调用SpringTransactionAnnotationParser的parseTransactionAnnotation方法:
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
if (attributes != null) {
/* 解析事务注解属性 */
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
至此,我们终于看到的Transactional注解,下面无疑就是解析注解当中声明的属性了:
SpringTransactionAnnotationParser:
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<RollbackRuleAttribute>();
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;
}
在这个方法中我们看到了在@Transactional注解中声明的各种常用或者不常用的属性的解析,至此,事务的初始化工作算是完成了,我们会在下片文章中继续分析Spring事务的执行过程。