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上,從而實現事務的代理加強。