springBoot事务基本原理是基于spring的BeanPostProcessor,在springBoot中事务使用方式为:
一、在启动类上添加注解:@EnableTransactionManagement
二、在需要事务的接口上添加注解:@Transactional
基本原理:
注解:@EnableTransactionManagement 存在一个import :
@Import(TransactionManagementConfigurationSelector.class)
TransactionManagementConfigurationSelector 继承树为:
由此可以看到,TransactionManagementConfigurationSelector 继承自:
AdviceModeImportSelector
该类又实现了:
ImportSelector
重写了接口:
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;}}
AdviceMode :默认属性为:PROXY
TransactionManagementConfigurationSelector:又导入了两个类,分别为:①AutoProxyRegistrar②ProxyTransactionManagementConfiguration
分析①AutoProxyRegistrar 该类实现接口:ImportBeanDefinitionRegistrar;通过registerBeanDefinitions 向容器中注入了组件,添加后置处理器
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean candidateFound = false;Set 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;}}}}if (!candidateFound && logger.isInfoEnabled()) {String name = getClass().getSimpleName();logger.info(String.format("%s was imported but no annotations were found " +"having both 'mode' and 'proxyTargetClass' attributes of type " +"AdviceMode and boolean respectively. This means that auto proxy " +"creator registration and configuration may not have occurred as " +"intended, and components may not be proxied as expected. Check to " +"ensure that %s has been @Import'ed on the same class where these " +"annotations are declared; otherwise remove the import of %s " +"altogether.", name, name, name));}}
向容器注入组件:InfrastructureAdvisorAutoProxyCreator
private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);if (!cls.getName().equals(apcDefinition.getBeanClassName())) {int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority = findPriorityForClass(cls);if (currentPriority < requiredPriority) {apcDefinition.setBeanClassName(cls.getName());}}return null;}//注册一个BeanDefinitionRootBeanDefinition beanDefinition = new RootBeanDefinition(cls);beanDefinition.setSource(source);beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);return beanDefinition;}
主要添加一个bean的后置处理器:InfrastructureAdvisorAutoProxyCreator
@Nullablepublic static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);}
InfrastructureAdvisorAutoProxyCreator 继承类图可见:
SmartInstantiationAwareBeanPostProcessor -》InstantiationAwareBeanPostProcessor-》BeanPostProcessor
在类:AbstractAutoProxyCreator 重写了postProcessBeforeInitialization和postProcessAfterInitialization接口,其中after接口定义如下:
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;}//创建代理对象//参数:当前bean,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;}
②:ProxyTransactionManagementConfiguration 是一个配置类,用于注册启用基于代理的注释驱动的事务管理所必需的 Spring 基础结构 bean。注册了三个bean,分别是:
1):BeanFactoryTransactionAttributeSourceAdvisor:事务通知器
@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.getNumber("order"));}return advisor;}
2):TransactionAttributeSource:一个事务属性相关来源,知道如何获取事务属性,无论是从配置、源代码级别的元数据属性(如注释)还是其他任何位置,解析注解的属性
@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}
3):TransactionInterceptor:事务拦截器,具体执行事务的相关内容就在此处。
@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;}
执行事务操作就在这个拦截器里面:
public Object invoke(MethodInvocation invocation) throws Throwable {// Work out the target class: may be {@code null}.// The TransactionAttributeSource should be passed the target class// as well as the method, which may be from an interface.Class> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// Adapt to TransactionAspectSupport's invokeWithinTransaction...return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {@Override@Nullable//重点在这咧public Object proceedWithInvocation() throws Throwable {return invocation.proceed();}@Overridepublic Object getTarget() {return invocation.getThis();}@Overridepublic Object[] getArguments() {return invocation.getArguments();}});}
执行事务调用代码:
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {// Standard transaction demarcation with getTransaction and commit/rollback calls.//创建一个事务TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {// This is an around advice: Invoke the next interceptor in the chain.// This will normally result in a target object being invoked.//执行被代理的方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {// target invocation exception//如果有异常就执行回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {//清空事务cleanupTransactionInfo(txInfo);}if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {// Set rollback-only in case of Vavr failure matching our rollback rules...TransactionStatus status = txInfo.getTransactionStatus();if (status != null && txAttr != null) {retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}}//提交事务commitTransactionAfterReturning(txInfo);return retVal;}
以上就是spring事务的简单基本原理,不过分深究。核心的核心就是spring的后置处理机制。包括:BeanFactoryPostProcessor和BeanPostProcessor这两个关键的后置处理机制,在初始化前后对bean进行扩展处理。