zoukankan      html  css  js  c++  java
  • spring事物源码分析篇三:spring事物标签的解析

    <tx:annotation-driven transaction-manager="transactionManager" /> 事物标签用于开启spring事物,如果不存在此标签,那么spring将不存在事物的功能。Spring通过自定义标签解析事物标签。在spring-tx-4.3.2.RELEASE.jar下面的自定义标签解析的配置下面配置了TxNamespaceHandler 用于解析事物标签的handler

    寻找到TxNamespaceHandler 并对init代码进行分析:

    public class TxNamespaceHandler extends NamespaceHandlerSupport {
    
        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);
        }
    
    
        @Override
        public void init() {
            registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
            // 解析事物标签annotation-driven
            registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
            registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
        }
    
    }

     进入解析类的解析方法:

        @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            registerTransactionalEventListenerFactory(parserContext);
            String mode = element.getAttribute("mode");
            if ("aspectj".equals(mode)) {
                // mode="aspectj"
                registerTransactionAspect(element, parserContext);
            }
            else {
                // mode="proxy" 如果没有配置mode属性值 会执行这里
                AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
            }
            return null;
        }

    进一步跟进代码:

    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);
    
                    // Create the TransactionAttributeSource definition.
                   // 创建 AnnotationTransactionAttributeSource实体  
                    RootBeanDefinition sourceDef = new RootBeanDefinition(
                            "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
                    sourceDef.setSource(eleSource);
                    sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
               //使用spring的规则生成beanName
                    String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
    
                    // Create the TransactionInterceptor definition.
                   // 创建TransactionInterceptor实体
                    RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
                    interceptorDef.setSource(eleSource);
                    interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                    registerTransactionManager(element, interceptorDef);
                    interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                   // 使用spring定义的规则 ,生成beanName
                    String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
    
                     // Create the TransactionAttributeSourceAdvisor definition.
                    //创建BeanFactoryTransactionAttributeSourceAdvisor实体
                    RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
                    advisorDef.setSource(eleSource);
                    advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                   // 将之前创建的实体分别放入advisorDef中
                    advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                    advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                    if (element.hasAttribute("order")) {
                        advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
                    }
                    //使用spring定义的规则生成beanName
                    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);
                }
            }

    然后继续分析第一行代码:

    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

    进入代码:

    public static void registerAutoProxyCreatorIfNecessary(
                ParserContext parserContext, Element sourceElement) {
    
            BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
                    parserContext.getRegistry(), parserContext.extractSource(sourceElement));
            useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
            registerComponentIfNecessary(beanDefinition, parserContext);
        }

    进一步分析代码可以看到:InfrastructureAdvisorAutoProxyCreator 继承了BeanPostProcessor接口,然后在父类AbstractAutoProxyCreatorpostProcessAfterInitialization中实现了寻找增强器的逻辑,而postProcessAfterInitialization方法在userService实例化的时候执行。

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
                //根据给定的bean的class和name 构建beanCass_name
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
               //是避免循环依赖而创建的bean代理
                if (!this.earlyProxyReferences.contains(cacheKey)) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }

    然后继续进入代码:wrapIfNecessary(bean, beanName, cacheKey);

    /**
         * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
         * @param bean the raw bean instance
         * @param beanName the name of the bean
         * @param cacheKey the cache key for metadata access
         * @return a proxy wrapping the bean, or the raw bean instance as-is
         */
        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;
            }
           // 给到的bean是否代表着一个基础设施类,或者设置不需要进行代理
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // Create proxy if we have advice.
            // 找出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;
        }

    进入获取增强器方法:

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

    进一步的深入分析:

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

    进入获取候选增强器代码进行分析:

    /**
         * Find all eligible Advisor beans in the current bean factory,
         * ignoring FactoryBeans and excluding beans that are currently in creation.
         * @return the list of {@link org.springframework.aop.Advisor} beans
         * @see #isEligibleBean
         */
        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!
                   // 获取所有Advisor类型的beanName
                    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 {
                            //根据获取Advisor类型的beanName获取对应的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());
                                    }
                                    // 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;
        }

    下面进一步分析在候选增强器中寻找匹配项:

    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;
                }
    //对普通增强的处理
                if (canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            return eligibleAdvisors;
        }

    // 进一步的分析代码

    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
            if (advisor instanceof IntroductionAdvisor) {
                return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
            }
           //RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
    创建的BeanFactoryTransactionAttributeSourceAdvisor类刚好实现了PointcutAdvisor接口,因此代码会走这里
    else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } }

    继续深入代码进行分析:

    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) {
                // No need to iterate the methods if we're matching any method anyway...
                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)) ||
                           // 此时调用的是TransactionAttributeSourcePointcut类
                            methodMatcher.matches(method, targetClass)) {
                        return true;
                    }
                }
            }
    
            return false;
        }

    进入TransactionAttributeSourcePointcut类中的matches方法

        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            if (TransactionalProxy.class.isAssignableFrom(targetClass)) {
                return false;
            }
            TransactionAttributeSource tas = getTransactionAttributeSource();
            return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
        }

    进一步代码分析:

    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.
                 //  选择事物标签的代码  spring寻找事物的逻辑:1.先在实现类方法中寻找 2.
                //   在实现类上面找 3.在接口方法中找 4.在接口类中找 
                TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);
                // Put it in the cache.
                if (txAtt == null) {
                    this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
                }
                else {
                    if (logger.isDebugEnabled()) {
                        Class<?> classToLog = (targetClass != null ? targetClass : method.getDeclaringClass());
                        logger.debug("Adding transactional method '" + classToLog.getSimpleName() + "." +
                                method.getName() + "' with attribute: " + txAtt);
                    }
                    this.attributeCache.put(cacheKey, txAtt);
                }
                return txAtt;
            }
        }

     spring通过提取事物标签,来在候选增强器中获取对应匹配项,然后生成相应的代理对象。在业务代码执行的时候,执行代理对象的invoke方法

  • 相关阅读:
    链表的相关操作
    【回溯】旅行商问题
    【回溯】图的m着色问题
    奶牛卧室_待解决
    阶乘问题
    子数整数
    hihoCoder week4 Trie图
    hihoCoder week3 KMP算法
    hihoCoder week2 Trie树
    hihoCoder week1 最长回文子串
  • 原文地址:https://www.cnblogs.com/histlyb/p/9759955.html
Copyright © 2011-2022 走看看