Spring提取@Transactional事务注解的源码解析

来源:互联网 发布:金融行业前景知乎 编辑:程序博客网 时间:2024/06/06 05:01

Spring提取@Transactional事务注解的源码解析

声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记; 难免有错误,敬请读者谅解!!!

1、事务注解标签

    <tx:annotation-driven />

2、tx 命名空间解析器 
事务tx命名空间解析器TxNamespaceHandler 
org.springframework.transaction.config.TxNamespaceHandler#init

这里写图片描述

3、AnnotationDrivenBeanDefinitionParser#parse 解析事务标签

(1)、以下方法的核心逻辑主要是选择是否使用 Aspect 方式实现代理,默认方式为 JDK 的动态代理。 
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse

public BeanDefinition parse(Element element, ParserContext parserContext) {    String mode = element.getAttribute("mode");    if ("aspectj".equals(mode)) {        // mode="aspectj"        registerTransactionAspect(element, parserContext);    }    else {        // mode="proxy"   注意 AopAutoProxyConfigurer 为当前内的内部类        AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);    }    return null;}

(2)、进入如下方法,该方法的核心逻辑通过硬编码的方式配置 Aop 动态代理的解析器 
AopAutoProxyConfigurer#configureAutoProxyCreator 
通过硬编码,Spring 为我们定义了如下的 Spring BeanDefinition 对象 
(a)、AnnotationTransactionAttributeSource.class 事务注解属性解析器BeanDefinition 对象。 
AnnotationTransactionAttributeSource 构造方法会初始化:

public AnnotationTransactionAttributeSource() {        this(true);}public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {    this.publicMethodsOnly = publicMethodsOnly;    this.annotationParsers = new LinkedHashSet<TransactionAnnotationParser>(2);    this.annotationParsers.add(new SpringTransactionAnnotationParser());// @Transactional 注解解析器    if (ejb3Present) {        this.annotationParsers.add(new Ejb3TransactionAnnotationParser());// Ejb 解析器    }

(b)、TransactionInterceptor.class 事务拦截器BeanDefinition 对象 
(c)、BeanFactoryTransactionAttributeSourceAdvisor.class 事务切面解析器 
(d)、TransactionInterceptor.class 事务拦截器BeanDefinition 对象 
(e)、容易忽略的第一行代码:AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); 在这个方法内部 Spring 为我们的注入了:InfrastructureAdvisorAutoProxyCreator.class 
这里写图片描述

private static class AopAutoProxyConfigurer {    public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {        // 非常重要的一行代码,在这个里面注册了:InfrastructureAdvisorAutoProxyCreator.class 该类实现了Spring BeanProcessor 的扩展接口        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(AnnotationTransactionAttributeSource.class);// 事务注解解析器            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);        }    }}

4、Spring Bean 实例化创建代理对象 
(a)、AbstractAutowireCapableBeanFactory#initializeBean(Java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

这里写图片描述

(b)、AbstractAutoProxyCreator#postProcessAfterInitialization 
这里写图片描述

还记得上面我们提到的 InfrastructureAdvisorAutoProxyCreator 的类图吧,最后我们的 @Transactional 注解的类会执行该类中的 postProcessAfterInitialization 方法

(c)、Bean 的初始化后置处理,通过注释可以了解到,当前方法处理后会返回一个 bean 的代理对象

/** * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * @see #getAdvicesAndAdvisorsForBean */public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {    if (bean != null) {        Object cacheKey = getCacheKey(bean.getClass(), beanName);        if (!this.earlyProxyReferences.containsKey(cacheKey)) {            return wrapIfNecessary(bean, beanName, cacheKey);// 创建代理类的核心方法        }    }    return bean;}

(d)、AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {    if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {        return bean;    }    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {        return bean;    }    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {        this.advisedBeans.put(cacheKey, Boolean.FALSE);        return bean;    }    // Create proxy if we have advice.   获取切面   获取的过程是一个非常复杂的过程    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);    if (specificInterceptors != DO_NOT_PROXY) {        this.advisedBeans.put(cacheKey, Boolean.TRUE);        // 创建代理对象,默认的情况下会使用 JDK 的动态代理接口创建代理对象        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;}

(c)、获取到的事务切面 
这里写图片描述

(d)、事务切面获取逻辑 
这里写图片描述

(e)、委托 ProxyFactory 创建代理对象

protected Object createProxy(        Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {    ProxyFactory proxyFactory = new ProxyFactory();    // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.    proxyFactory.copyFrom(this);    if (!shouldProxyTargetClass(beanClass, beanName)) {        // Must allow for introductions; can't just set interfaces to        // the target's interfaces only.        Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);        for (Class<?> targetInterface : targetInterfaces) {            proxyFactory.addInterface(targetInterface);        }    }    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);    for (Advisor advisor : advisors) {        proxyFactory.addAdvisor(advisor);    }    proxyFactory.setTargetSource(targetSource);    customizeProxyFactory(proxyFactory);    proxyFactory.setFrozen(this.freezeProxy);    if (advisorsPreFiltered()) {        proxyFactory.setPreFiltered(true);    }    // 最终会使用:JdkDynamicAopProxy  创建事务的Aop 代理对象    return proxyFactory.getProxy(this.proxyClassLoader);}

(f)、最终生成代理对象 
这里写图片描述

5、代理类执行 
JdkDynamicAopProxy#invoke

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    MethodInvocation invocation;    Object oldProxy = null;    boolean setProxyContext = false;    TargetSource targetSource = this.advised.targetSource;    Class<?> targetClass = null;    Object target = null;    try {        // 如果目标方法没有实现equals        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {            // The target does not implement the equals(Object) method itself.            return equals(args[0]);        }        // 如果目标方法没有实现hashcode        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {            // The target does not implement the hashCode() method itself.            return hashCode();        }        // 根据代理对象的配置来调用服务        if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&                method.getDeclaringClass().isAssignableFrom(Advised.class)) {            // Service invocations on ProxyConfig with the proxy config...            return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);        }        Object retVal;        if (this.advised.exposeProxy) {            // Make invocation available if necessary.            oldProxy = AopContext.setCurrentProxy(proxy);            setProxyContext = true;        }        // May be null. Get as late as possible to minimize the time we "own" the target,        // in case it comes from a pool.        // 获取目标对象        target = targetSource.getTarget();        if (target != null) {            targetClass = target.getClass();        }        // 获取定义好的拦截器链        // Get the interception chain for this method.        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);        // Check whether we have any advice. If we don't, we can fallback on direct        // reflective invocation of the target, and avoid creating a MethodInvocation.        if (chain.isEmpty()) {            // We can skip creating a MethodInvocation: just invoke the target directly            // Note that the final invoker must be an InvokerInterceptor so we know it does            // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.            // 没有拦截链则直接调用target方法            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);        }        else {            // We need to create a method invocation...            //对拦截链进行封装  得到对象ReflectiveMethodInvocation 调用 proceed 方法            invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);            // Proceed to the joinpoint through the interceptor chain.            retVal = invocation.proceed();// 方法内部将执行拦截器的切面直到目标方法被执行        }        // Massage return value if necessary.        Class<?> returnType = method.getReturnType();        if (retVal != null && retVal == target && returnType.isInstance(proxy) &&                !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {            // Special case: it returned "this" and the return type of the method            // is type-compatible. Note that we can't help if the target sets            // a reference to itself in another returned object.            retVal = proxy;        }        else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {            throw new AopInvocationException(                    "Null return value from advice does not match primitive return type for: " + method);        }        return retVal;    }    finally {        if (target != null && !targetSource.isStatic()) {            // Must have come from TargetSource.            targetSource.releaseTarget(target);        }        if (setProxyContext) {            // Restore old proxy.            AopContext.setCurrentProxy(oldProxy);        }    }}

7、代理会执行到: ReflectiveMethodInvocation#proceed 方法

8、最终会执行到:TransactionInterceptor#invoke 方法

这里写图片描述

9、执行 TransactionAspectSupport 事务方法 
TransactionInterceptor#invoke 方法会调用到父类的 TransactionAspectSupport#invokeWithinTransaction 方法

这里写图片描述

10、业务方法执行 
这里写图片描述

11、Spring 事务处理的流程 
这里写图片描述

(a)、开启事务 
这里写图片描述

(b)、事务回滚 
这里写图片描述

(c)、事务提交 
这里写图片描述

 
 http://blog.csdn.net/dalinsi/article/details/53203540

 

 

声明:本编文章是自己在查看spring提取@Transactional注解的源码过程中随手记下的笔记,只做了大概流程的记录,未做详细分析,如有错误还请谅解。

这里写图片描述

1、事务切面匹配处理类

AopUtils#canApply(Pointcut, Class , boolean) 
方法中会调用到 TransactionAttributeSourcePointcut#matches 方法

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 HashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));    classes.add(targetClass);    for (Class<?> clazz : classes) {        Method[] methods = clazz.getMethods();        for (Method method : methods) {            //methodMatcher.matches(method, targetClass) 方法会匹配对应的处理类,在Transaction提取的过程中会匹配到:TransactionAttributeSourcePointcut             if ((introductionAwareMethodMatcher != null &&                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||                    methodMatcher.matches(method, targetClass)) {                return true;            }        }    }    return false;}

这里写图片描述

2、事务切点匹配

TransactionAttributeSourcePointcut#matches

在阅读TransactionAttributeSourcePointcut内的源代码的时候,我们发现该类是一个抽象,但是他确没有实现的子类!!!那么这个类到底在哪被引用了呢?

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {    public boolean matches(Method method, Class targetClass) {        // 该处调用了 getTransactionAttributeSource() 的抽象方法,但是却没有子类实现这个方法,这是怎么一回事呢?        TransactionAttributeSource tas = getTransactionAttributeSource();        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);    }    @Override    public boolean equals(Object other) {        if (this == other) {            return true;        }        if (!(other instanceof TransactionAttributeSourcePointcut)) {            return false;        }        TransactionAttributeSourcePointcut otherPc = (TransactionAttributeSourcePointcut) other;        return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());    }    @Override    public int hashCode() {        return TransactionAttributeSourcePointcut.class.hashCode();    }    @Override    public String toString() {        return getClass().getName() + ": " + getTransactionAttributeSource();    }    /**     * Obtain the underlying TransactionAttributeSource (may be {@code null}).     * To be implemented by subclasses.     */    protected abstract TransactionAttributeSource getTransactionAttributeSource();}

3、TransactionAttributeSourcePointcut 抽象类的应用

我们怀着上面的疑问全局搜索 TransactionAttributeSourcePointcut 可以在 BeanFactoryTransactionAttributeSourceAdvisor 里面找到如下的代码:

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {    private TransactionAttributeSource transactionAttributeSource;    // 此处利用了匿名内部类的方式实例化了 TransactionAttributeSourcePointcut 对象,在此我们找到了上面问题的答案。    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {        @Override        protected TransactionAttributeSource getTransactionAttributeSource() {            return transactionAttributeSource;        }    };    /**     * Set the transaction attribute source which is used to find transaction     * attributes. This should usually be identical to the source reference     * set on the transaction interceptor itself.     * @see TransactionInterceptor#setTransactionAttributeSource     */    public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {        this.transactionAttributeSource = transactionAttributeSource;    }    /**     * Set the {@link ClassFilter} to use for this pointcut.     * Default is {@link ClassFilter#TRUE}.     */    public void setClassFilter(ClassFilter classFilter) {        this.pointcut.setClassFilter(classFilter);    }    public Pointcut getPointcut() {        return this.pointcut;    }}

3、TransactionAttributeSource 属性的 Bean 定义过程

其实,在实例化 BeanFactoryTransactionAttributeSourceAdvisor 时,Spring 已经为我们的 BeanFactoryTransactionAttributeSourceAdvisor 设置了 TransactionAttributeSource 属性,可以进入 AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator 方法中看源代码:

private static class 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);            // 注解事务 transactionAttributeSource Spring 定义的Bean为: AnnotationTransactionAttributeSource 实例            // Create the TransactionAttributeSource definition.            RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class);            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 BeanFactoryTransactionAttributeSourceAdvisor Bean 的定义            // Create the TransactionAttributeSourceAdvisor definition.            RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);            advisorDef.setSource(eleSource);            advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);            // 设置 transactionAttributeSource 属性            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);        }    }}

4、TransactionAttributeSource#getTransactionAttribute 方法的调用过程

通过以上的分析,我们可以确定 
TransactionAttributeSourcePointcut#getTransactionAttributeSource 返回的是:AnnotationTransactionAttributeSource 实例,AnnotationTransactionAttributeSource继承自:AbstractFallbackTransactionAttributeSource, 故此TransactionAttributeSourcePointcut#matches 最终会调用到 AbstractFallbackTransactionAttributeSource#getTransactionAttribute 方法

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {    public boolean matches(Method method, Class targetClass) {        TransactionAttributeSource tas = getTransactionAttributeSource();        // 最终会调用到 AbstractFallbackTransactionAttributeSource#getTransactionAttribute 方法        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);    }    // 省略其他代码 ……………………}

再看 AbstractFallbackTransactionAttributeSource#getTransactionAttribute 方法

// 获取事务属性public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {    // First, see if we have a cached value.    Object cacheKey = getCacheKey(method, targetClass);    Object cached = this.attributeCache.get(cacheKey);    if (cached != null) {        // Value will either be canonical value indicating there is no transaction attribute,        // or an actual transaction attribute.        if (cached == NULL_TRANSACTION_ATTRIBUTE) {            return null;        }        else {            return (TransactionAttribute) cached;        }    }    else {        // We need to work it out.  根据 method、targetClass 推算事务属性,TransactionAttribute         TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);        // Put it in the cache.        if (txAtt == null) {            this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);        }        else {            if (logger.isDebugEnabled()) {                logger.debug("Adding transactional method '" + method.getName() + "' with attribute: " + txAtt);            }            this.attributeCache.put(cacheKey, txAtt);        }        return txAtt;    }}

5、事务属性的推算过程:

// 推算事务属性,TransactionAttribute private TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {    // Don't allow no-public methods as required.    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {        return null;    }    // Ignore CGLIB subclasses - introspect the actual user class.    Class<?> userClass = ClassUtils.getUserClass(targetClass);    // The method may be on an interface, but we need attributes from the target class.    // If the target class is null, the method will be unchanged.    Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);    // If we are dealing with method with generic parameters, find the original method.    specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);    // 通过上面的分析,findTransactionAttribute 该方法最终会调用到:AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.Class<?>)     // First try is the method in the target class. 方式1: 从目标类的方法上找 Transaction注解    TransactionAttribute txAtt = findTransactionAttribute(specificMethod);    if (txAtt != null) {        return txAtt;    }    // Second try is the transaction attribute on the target class.  方式2: 从目标类上找 Transaction注解    txAtt = findTransactionAttribute(specificMethod.getDeclaringClass());    if (txAtt != null) {        return txAtt;    }    if (specificMethod != method) {// 以上两种方式如果还没有找到 TransactionAttribute 属性,那就要从目标类的接口开始找        // Fallback is to look at the original method.  方式3:接口的方法上找 Transaction注解        txAtt = findTransactionAttribute(method);        if (txAtt != null) {            return txAtt;        }        // Last fallback is the class of the original method.  方式4:接口的类上找 Transaction注解        return findTransactionAttribute(method.getDeclaringClass());    }    return null;}

6、事务注解属性的解析

AnnotationTransactionAttributeSource#findTransactionAttribute(Java.lang.Class

7、获取事务注解

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {    public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {        //获取 Transactional 注解        Transactional ann = AnnotationUtils.getAnnotation(ae, Transactional.class);        if (ann != null) {            //从 @Transactional 注解上获取事务属性值,并包装成 TransactionAttribute 返回            return parseTransactionAnnotation(ann);        }        else {            return null;        }    }    public TransactionAttribute parseTransactionAnnotation(Transactional ann) {        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();        rbta.setPropagationBehavior(ann.propagation().value());        rbta.setIsolationLevel(ann.isolation().value());        rbta.setTimeout(ann.timeout());        rbta.setReadOnly(ann.readOnly());        rbta.setQualifier(ann.value());        ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();        Class[] rbf = ann.rollbackFor();        for (Class rbRule : rbf) {            RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);            rollBackRules.add(rule);        }        String[] rbfc = ann.rollbackForClassName();        for (String rbRule : rbfc) {            RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);            rollBackRules.add(rule);        }        Class[] nrbf = ann.noRollbackFor();        for (Class rbRule : nrbf) {            NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);            rollBackRules.add(rule);        }        String[] nrbfc = ann.noRollbackForClassName();        for (String rbRule : nrbfc) {            NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);            rollBackRules.add(rule);        }        rbta.getRollbackRules().addAll(rollBackRules);        return rbta;    }    @Override    public boolean equals(Object other) {        return (this == other || other instanceof SpringTransactionAnnotationParser);    }    @Override    public int hashCode() {        return SpringTransactionAnnotationParser.class.hashCode();    }}
原创粉丝点击