• springboot启动流程(十二)springboot事务自动配置


    所有文章

    https://www.cnblogs.com/lay2017/p/11478237.html

    正文

    上一篇文章中,我们简单了解了aop的处理过程。代理增强之前,先生成Advisor,然后利用cglib或者jdk动态代理把可以应用到当前Bean的Advisor增强到Bean上。

    springboot的事务,也是基于aop实现。那么我们就需要把事务相关的配置生成Advisor,然后一样地增强到Bean上。

    生成Advisor

    首先,我们先找到事务的自动配置类TransactionAutoConfiguration

    @Configuration
    @ConditionalOnClass(PlatformTransactionManager.class)
    @AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
            DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
    @EnableConfigurationProperties(TransactionProperties.class)
    public class TransactionAutoConfiguration {
        // 省略
    
        @Configuration
        @ConditionalOnBean(PlatformTransactionManager.class)
        @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
        public static class EnableTransactionManagementConfiguration {
    
            // 省略
    
            @Configuration
            @EnableTransactionManagement(proxyTargetClass = true)
            @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
            public static class CglibAutoProxyConfiguration {
    
            }
    
        }
    
    }

    这里,我们注意到@EnableTransactionManagement这个注解。熟悉spring的我们都知道,这个意味着开启事务管理。我们打开这个注解

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(TransactionManagementConfigurationSelector.class)
    public @interface EnableTransactionManagement {
        //
    }

    跟其它@Enable ** 形式的注解一样,通过@Import注解导入了一个类,跟进TransactionManagementConfigurationSelector看看

    public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    
        @Override
        protected String[] selectImports(AdviceMode adviceMode) {
            switch (adviceMode) {
                // 默认是proxy
                case PROXY:
                    return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
                case ASPECTJ:
                    return new String[] {determineTransactionAspectClass()};
                default:
                    return null;
            }
        }
    
        //
    
    }

    这里将会导入两个类AutoProxyRegistrar和ProxyTransactionManagementConfiguration,前者是处理代理,后者是处理事务配置的。上一篇讲述aop的时候我们说过,创建代理将会通过AnnotationAwareAspectJAutoProxyCreator来处理,所以这里的AutoProxyRegistrar比AnnotationAwareAspectJAutoProxyCreator的优先级低。

    ProxyTransactionManagementConfiguration是处理事务配置的,我们跟进它

    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
        @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
            BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor());
            if (this.enableTx != null) {
                advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            }
            return advisor;
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionInterceptor transactionInterceptor() {
            TransactionInterceptor interceptor = new TransactionInterceptor();
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            if (this.txManager != null) {
                interceptor.setTransactionManager(this.txManager);
            }
            return interceptor;
        }
    
    }

    正如我们开篇说的,事务是基于aop的,会去生成Advisor。我们看到transactionAdvisor将会返回一个BeanFactoryTransactionAttributeSourceAdvisor。我们看看它的uml类图

    这里就是生成了一个Advisor,并作为Bean存在于BeanFactory当中。

    增强到Bean

    我们打开AbstractAutoProxyCreator的wrapIfNecessary方法

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //
    
        // 获取可以增强到当前Bean的Advisor
        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;
    }

    getAdvicesAndAdvisorsForBean将会获取到事务生成的Advisor,然后createProxy将会进行代理增强,cglib或者jdk动态代理的方式。

    跟进AbstractAdvisorAutoProxyCreator的findEligibleAdvisors方法

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 找到Bean工厂里所有Advisor
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 获取可以增强到当前Bean的Advisor    
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

    跟进findAdvisorsThatCanApply看看怎么判断是否可以增强

    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            // 找到可以增强的Advisor
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }

    继续跟进findAdvisorsThatCanApply

    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        //
    
        List<Advisor> eligibleAdvisors = new ArrayList<>();
    
        //
    
        for (Advisor candidate : candidateAdvisors) {
            //
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        
        return eligibleAdvisors;
    }

    判断逻辑落在了canApply方法上,跟进它

    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;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            return true;
        }
    }

    这里的canApply将会判断PointcutAdvisor是否能增强到targetClass上,继续跟进canApply

    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        //
    
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        //
    
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }
    
        Set<Class<?>> classes = new LinkedHashSet<>();
        if (!Proxy.isProxyClass(targetClass)) {
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(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;
    }

    总结

    本文简单过了一下事务的自动配置到代理增强。事务基于自动配置机制和aop,自动配置机制将会生成Advisor,然后通过代理增强到Bean上,从而实现事务的代理增强。

  • 相关阅读:
    网络爬虫之框架(Scrapy)
    模拟投币试验
    [LeetCode#177]Nth Highest Salary
    Windows Server 2008 各版本功能差异与比较各版本概观--转载
    Win2008 R2下Server Core常用命令小结
    powershell 中用Sqlps管理我台sqlserver 2008r2
    初识 Markdown
    React 入门(3): 严格模式 ReactDOM
    ES6 类的正确定义方式 公有类字段 getter / setter
    Lodash 去抖动 节流
  • 原文地址:https://www.cnblogs.com/lay2017/p/11530742.html
Copyright © 2020-2023  润新知