目录
ProxyTransactionManagementConfiguration.class
TransactionInterceptor类下的invoke()方法
一、入口
package com.xiaojie.spring;import com.mysql.cj.jdbc.MysqlDataSource;import org.springframework.context.annotation.*;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;/* * * @param null * 配置类 * @author xiaojie * @date 2021/8/24 * @return */@Configuration@ComponentScan("com.xiaojie")@EnableTransactionManagementpublic class Config { /* * * 加载数据源 * @author xiaojie * @date 2021/8/24 * @return javax.sql.DataSource */ @Bean DataSource dataSource(){ MysqlDataSource mysqlDataSource = new MysqlDataSource(); mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/order?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai"); mysqlDataSource.setUser("root"); mysqlDataSource.setPassword("root");// mysqlDataSource.setDatabaseName("order"); return mysqlDataSource; } /* * 加载事务管理器 * @author xiaojie * @date 2021/8/24 * @return org.springframework.transaction.PlatformTransactionManager */ @Bean PlatformTransactionManager platformTransactionManager(){ return new DataSourceTransactionManager(dataSource()); } /* *数据库连接 * @author xiaojie * @date 2021/8/24 * @return org.springframework.jdbc.core.JdbcTemplate */ @Bean JdbcTemplate jdbcTemplate(){ return new JdbcTemplate(dataSource()); }}
@EnableTransactionManagement 为事务的入口
二、流程图
三 、源码
AutoProxyRegistrar
//默认是代理模式
if (mode == AdviceMode.PROXY) {
//注册InfrastructureAdvisorAutoProxyCreator.class类到ioc容器
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
AopConfigUtils
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;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
上述注册完之后会将InfrastructureAdvisorAutoProxyCreator.class类注入到IOC中
beanId:org.springframework.aop.config.internalAutoProxyCreator
Class:InfrastructureAdvisorAutoProxyCreator.class
由类图InfrastructureAdvisorAutoProxyCreator.class继承了BeanPostProcessor同样会执行前置增强或者后置增强。
ProxyTransactionManagementConfiguration.class
//将TransactionInterceptor 类注入到IOC
@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;
}
再看BeanPostProcessor后置增强方法
然后就会发现跟AOP的代码是一样的SpringAop学习笔记(三)——Aop源码分析
JdkDynamicAopProxy下invoke()
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
.........省略
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//由此进入proceed()方法
retVal = invocation.proceed();
}
.........省略
}
ReflectiveMethodInvocation
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//此处用到了责任链设计模式+递归思想实现所有的通知增强
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
MethodInterceptor
Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;
TransactionInterceptor类下的invoke()方法
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
......省略
TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
//执行目标方法
retVal = invocation.proceedWithInvocation();
} catch (Throwable var20) {
//发生异常 则执行事务回滚
this.completeTransactionAfterThrowing(txInfo, var20);
throw var20;
} finally {
//将当前事务归还ThreadLocal<TransactionAspectSupport.TransactionInfo>
this.cleanupTransactionInfo(txInfo);
}
if (retVal != null && vavrPresent && TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//提交事务
this.commitTransactionAfterReturning(txInfo);
return retVal;
.........省略
}
Spring 版本为5.3.9
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/18524.html