• 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;
        }
    
    }
    

    4、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);
            }
        }
    }
    

    5、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;
        }
    }
    

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

    // 推算事务属性,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;
    }
    

    7、事务注解属性的解析

    AnnotationTransactionAttributeSource#findTransactionAttribute(Java.lang.Class

    8、获取事务注解

    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();
        }
    
    }


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

  • 相关阅读:
    React项目升级遇到的问题复盘(2019-09-02)
    前端项目升级到React-router5中遇到的问题解决方案以及思路
    三行Jquery代码实现简单的选项卡
    开放-封闭原则
    单一职责原则
    简单工厂模式(c++实现)
    博客园使用MarkDown格式记录博客
    Qml 的Image对应的source不变,但是图片内容改变却不会刷新的解决方案
    Qt中第一请求web api连接返回缓慢问题
    Qt的pro文件工程配置
  • 原文地址:https://www.cnblogs.com/softidea/p/6854982.html
Copyright © 2020-2023  润新知