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上,从而实现事务的代理增强。