Spring事务的aop浅析
结合之前说到的SpringAop浅析(二)本篇将从事务的角度,来看下spring
或者说springboot
是如何通过一些简单的配置就可以将一些方法进行事务的管理,并了解一些事务在管理过程中的一些简单api
。
浅析
在没有spring
之前,或者说在不引入spring
的时候,在获取数据库访问的时候,通常是通过Connection
来进行。通过Connection
类来进行sql
的执行操作,然后在sql
执行完毕之后调用commit()
方法,将事务提交,当然了,在借助spring
框架之后,在编码过程中,再也没有通过这种方式来进行事务的提交。但是大差不差,这些事情是一定要做的,既然我们在编码过程中没有做,那么这件事情就一定被spring
做了。
1 2 3 4
| Connection conn = getConnection(); conn.setAutoCommit(false);
conn.commit();
|
根据上篇文章springAop
,不难猜测,spring
肯定是借助于aop
,对标记了@Transactional
的方法进行拦截并进行事务的增强。那么它是怎么实现的呢?
在spring
中开启事务需要通过EnableTransactionManagement
注解,实际上就是通过它来进行一些开箱即用的处理。这个注解的实现上引入了@Import
注解,这个注解的作用是为了将某些类引入到Spring
容器中。这样做有一个好处是,在启用这个注解的情况下,才引入某些类到容器中。
1 2 3 4 5 6 7 8 9 10
| @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
|
进入到TransactionManagementConfigurationSelector
类中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String[] {determineTransactionAspectClass()}; default: return null; } } }
|
重点来了,这里引入了两个类:
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
1.AutoProxyRegistar
它实现了ImportBeanDefinitionRegistrar
接口。所以它的主要作用是将InfrastructureAdvisorAutoProxyCreator
这个后置处理器类注入到容器中,那么容器在进行每一个bean
对象初始化时都会将这个后置处理作用在对应的bean
上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; Set<String> annTypes = importingClassMetadata.getAnnotationTypes(); for (String annType : annTypes) { AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (candidate == null) { continue; } Object mode = candidate.get("mode"); Object proxyTargetClass = candidate.get("proxyTargetClass"); if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) { candidateFound = true; if (mode == AdviceMode.PROXY) { AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); if ((Boolean) proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); return; } } } } } }
|
来看一下InfrastructureAdvisorAutoProxyCreator
类。它自己本身没有什么太多的实现,它继承与AbstractAdvisorAutoProxyCreator
抽象类,这个抽象类实现了一些查询那些增强可以作用在目标bean
对象上处理。本篇想聊的后置处理的实现是在它的父类AbstractAutoProxyCreator
上。
1 2 3
| public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator { }
|
在AbstractAutoProxyCreator
中,实现了具体的后置处理的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
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; }
|
1.ProxyTransactionManagementConfiguration
上面已经给出了结论,这个类的作用是引入了事务处理需要使用到的增强类。使得springBean
对象在初始化时进入到后置处理器中,后置处理器再获取到这个类通过@Bean
注解注入到容器中的增强类,从而实现将需要进行事务处理的类进行代理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @Configuration(proxyBeanMethods = false) public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor( TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) { 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( TransactionAttributeSource transactionAttributeSource) { TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributeSource(transactionAttributeSource); if (this.txManager != null) { interceptor.setTransactionManager(this.txManager); } return interceptor; } }
|
接下来看一下BeanFactoryTransactionAttributeSourceAdvisor
类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() { @Override @Nullable protected TransactionAttributeSource getTransactionAttributeSource() { return transactionAttributeSource; } }; }
|
所以这里具体的匹配规则在类AnnotationTransactionAttributeSource
中。
具体的匹配规则在它的父类AbstractFallbackTransactionAttributeSource#getTransactionAttribute()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @Override @Nullable public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { if (method.getDeclaringClass() == Object.class) { return null; } Object cacheKey = getCacheKey(method, targetClass); TransactionAttribute cached = this.attributeCache.get(cacheKey); if (cached != null) { if (cached == NULL_TRANSACTION_ATTRIBUTE) { return null; } else { return cached; } } else { TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass); return txAttr; } }
@Nullable protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
TransactionAttribute txAttr = findTransactionAttribute(specificMethod); if (txAttr != null) { return txAttr; }
return null; }
|
再回到AnnotationTransactionAttributeSource
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @Override @Nullable protected TransactionAttribute findTransactionAttribute(Method method) { return determineTransactionAttribute(method); }
@Nullable protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) { for (TransactionAnnotationParser parser : this.annotationParsers) { TransactionAttribute attr = parser.parseTransactionAnnotation(element); if (attr != null) { return attr; } } return null; }
@Override @Nullable public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) { AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( element, Transactional.class, false, false); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } }
|
总结
spring
事务的代理是通过@EnableTransactionManagement
注解来开启,这个注解通过@Import
注解来导入两个类,一个类是后置处理器,它的作用是在每个bean
对象创建之后将第二个导入类中定义的增强作用在这个对象上,并形成代理对象。第二个导入类的作用是定义了一个增强,这个增强包含了如何确定切面、切点、连接点等信息,也包含了拦截的逻辑,也就是事务的开启、提交和回滚等处理。