本文基于 Spring Boot 项目测试,依赖的 Spring 源码版本为5.2.1,主要测试代码如下:

@EnableTransactionManagement
//@EnableAspectJAutoProxy(exposeProxy = true)
@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}
@Service
@Slf4j
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;

@Override
public void insert() {
Student student = new Student();
student.setName("test");
student.setAge(23);
student.setNo("1002");
studentDao.insert(student);
}
}

在之前讲Spring IOC相关的文章了讲到过 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 中调用了 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 方法,在这方法后面还调用了一个方法,主要就是用来完成AOP的,主要代码如下:

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性填充
populateBean(beanName, mbd, instanceWrapper);
// 执行后置处理器,aop就是在这里完成的处理
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

在 initializeBean 方法中会调用Bean的后置处理器( applyBeanPostProcessorsAfterInitialization() )来完成AOP代理,主要代码如下:

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

当调用到此方法时,可以看到 getBeanPostProcessors() 中有一个 AnnotationAwareAspectJAutoProxyCreator,如下:

从源码角度浅析 Spring  @Transactional 的代理过程_sed

之所以能获取到 AnnotationAwareAspectJAutoProxyCreator 是因为加了@EnableTransactionManagement注解,它引入了 TransactionManagementConfigurationSelector,而这个Selector中有段代码是这样的(会被调用到):

从源码角度浅析 Spring  @Transactional 的代理过程_sed_02

上图中红色区域返回了 AutoProxyRegistrar.class 和 ProxyTransactionManagementConfiguration.class(下文会用到),在spring初始化过程中会调用到 org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions ,从而调用到 org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired,有一段这样的代码:

从源码角度浅析 Spring  @Transactional 的代理过程_spring_03

后续又会调用到 org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition ,在这个方法中获取到了 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition,后续会添加到 BeanPostProcessors 中去,如下:

从源码角度浅析 Spring  @Transactional 的代理过程_spring_04

AnnotationAwareAspectJAutoProxyCreator 实现或继承了N多类,如下:

从源码角度浅析 Spring  @Transactional 的代理过程_spring_05

从这幅图说明他的功能很强大,这里不扩展讲。这个后置处理器会调用 postProcessAfterInitialization 方法,然后依次调用:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply
org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)
org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut#matches
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

下面我们重点看一下 org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute 方法,

@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 这里判断了只允许public修饰的方法,这就是为什么 @Transactional默认只对可见性为public的方法起作用
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}

// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

// 1.这里先从方法上面找@Transactional,所以方法上面加了注解的优先级会高于类上面加了注解的,因为找到了就返回
// First try is the method in the target class.
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}

// 2.这里是从类上面找@Transactional,如果类(StudentServiceImpl)上找不到,会从接口(StudentService)上找,找到就返回
// Second try is the transaction attribute on the target class.
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}

if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}

return null;
}

示例是将注解加载了类上,所以会走第2个逻辑,断点一直跟进去到:org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement),如下:

从源码角度浅析 Spring  @Transactional 的代理过程_sed_06

然后会调用 parseTransactionAnnotation 方法来处理,如下:

protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));

List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);

return rbta;
}

然后回到 org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute 中,可以看到返回的 TransactionAttribute 和我们设置的(或默认的)一样,如下:

从源码角度浅析 Spring  @Transactional 的代理过程_ide_07

然后将其放入缓存中(下次就可以直接从缓存中取):

从源码角度浅析 Spring  @Transactional 的代理过程_spring_08

继续执行直至回到 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 中,创建并返回代理对象:

Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

从源码角度浅析 Spring  @Transactional 的代理过程_spring_09

到这里,基本上就完成了 @Transactional 的代理过程。

上文提到过 ProxyTransactionManagementConfiguration.class ,在spring 初始化时会调用到这样一段代码:

从源码角度浅析 Spring  @Transactional 的代理过程_spring_10

图中重点是 org.springframework.transaction.interceptor.TransactionInterceptor,在调用接口进行插入操作时,会被这个拦截器所拦截,然后会调用到 org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction 方法,代码如下:

@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {

// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
final TransactionManager tm = determineTransactionManager(txAttr);

if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method +
". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(
method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}

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 (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;
}

// 编程式事务处理
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();

// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});

// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}

由于我们采用的注解方式,相当于声明式事务,所以会调用到 createTransactionIfNecessary 方法,代码如下:

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

// If no name specified, apply method identification as transaction name.
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}

TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 获取 TransactionStatus ,会根据当前配置的事物传播特性做出相应处理,从而返回合适的 TransactionStatus
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

有时间会继续分析 status = tm.getTransaction(txAttr) 里面的及相关代码。。。