http://www.javashuo.com/article/p-uvudtich-bm.htmlhtml
在上一篇文章中,咱们简单了解了aop的处理过程。代理加强以前,先生成Advisor,而后利用cglib或者jdk动态代理把能够应用到当前Bean的Advisor加强到Bean上。spring
springboot的事务,也是基于aop实现。那么咱们就须要把事务相关的配置生成Advisor,而后同样地加强到Bean上。springboot
首先,咱们先找到事务的自动配置类TransactionAutoConfigurationide
@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的咱们都知道,这个意味着开启事务管理。咱们打开这个注解this
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { // }
跟其它@Enable ** 形式的注解同样,经过@Import注解导入了一个类,跟进TransactionManagementConfigurationSelector看看spa
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的优先级低。3d
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类图code
这里就是生成了一个Advisor,并做为Bean存在于BeanFactory当中。orm
咱们打开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上,从而实现事务的代理加强。