zoukankan      html  css  js  c++  java
  • 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上,从而实现事务的代理增强。

  • 相关阅读:
    [python][django学习篇][9]设计正在博客视图(3)
    [python][django学习篇][8]django 视图(2) --简单模板
    [python][django学习篇][7]设计博客视图(1)
    [python][django学习篇][6]操作数据库
    [python][django学习篇][5]选择数据库版本(默认SQLite3) 与操作数据库
    [python][django学习篇][4]django完成数据库代码翻译:迁移数据库(migration)
    [python][django学习篇][3]创建django web的数据库模型
    [python][django学习篇][2]创建django app
    自动化监控利器-Zabbix深入配置和使用
    piwik安装部署最佳实践
  • 原文地址:https://www.cnblogs.com/lay2017/p/11530742.html
Copyright © 2011-2022 走看看