Spring提取@Transactional事务注解的源码解析
声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记; 难免有错误,敬请读者谅解!!!
1、事务注解标签
<tx:annotation-driven />
2、tx 命名空间解析器
事务tx命名空间解析器TxNamespaceHandler
org.springframework.transaction.config.TxNamespaceHandler#init
3、AnnotationDrivenBeanDefinitionParser#parse 解析事务标签
(1)、以下方法的核心逻辑主要是选择是否使用 Aspect 方式实现代理,默认方式为 JDK 的动态代理。
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
registerTransactionAspect(element, parserContext);
}
else {
// mode="proxy" 注意 AopAutoProxyConfigurer 为当前内的内部类
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
(2)、进入如下方法,该方法的核心逻辑通过硬编码的方式配置 Aop 动态代理的解析器
AopAutoProxyConfigurer#configureAutoProxyCreator
通过硬编码,Spring 为我们定义了如下的 Spring BeanDefinition 对象
(a)、AnnotationTransactionAttributeSource.class 事务注解属性解析器BeanDefinition 对象。
AnnotationTransactionAttributeSource 构造方法会初始化:
public AnnotationTransactionAttributeSource() {
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet<TransactionAnnotationParser>(2);
this.annotationParsers.add(new SpringTransactionAnnotationParser());// @Transactional 注解解析器
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());// Ejb 解析器
}
(b)、TransactionInterceptor.class 事务拦截器BeanDefinition 对象
(c)、BeanFactoryTransactionAttributeSourceAdvisor.class 事务切面解析器
(d)、TransactionInterceptor.class 事务拦截器BeanDefinition 对象
(e)、容易忽略的第一行代码:AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); 在这个方法内部 Spring 为我们的注入了:InfrastructureAdvisorAutoProxyCreator.class
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 非常重要的一行代码,在这个里面注册了:InfrastructureAdvisorAutoProxyCreator.class 该类实现了Spring BeanProcessor 的扩展接口
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// Create the TransactionAttributeSource definition.
RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class);// 事务注解解析器
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// Create the TransactionInterceptor definition.
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);//事务拦截器
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registerTransactionManager(element, interceptorDef);
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the TransactionAttributeSourceAdvisor definition.
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);//事务切面解析器
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
}
4、Spring Bean 实例化创建代理对象
(a)、AbstractAutowireCapableBeanFactory#initializeBean(Java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
(b)、AbstractAutoProxyCreator#postProcessAfterInitialization
还记得上面我们提到的 InfrastructureAdvisorAutoProxyCreator 的类图吧,最后我们的 @Transactional 注解的类会执行该类中的 postProcessAfterInitialization 方法
(c)、Bean 的初始化后置处理,通过注释可以了解到,当前方法处理后会返回一个 bean 的代理对象
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);// 创建代理类的核心方法
}
}
return bean;
}
(d)、AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.containsKey(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;
}
// Create proxy if we have advice. 获取切面 获取的过程是一个非常复杂的过程
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象,默认的情况下会使用 JDK 的动态代理接口创建代理对象
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;
}
(c)、获取到的事务切面
(d)、事务切面获取逻辑
(e)、委托 ProxyFactory 创建代理对象
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
proxyFactory.addInterface(targetInterface);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 最终会使用:JdkDynamicAopProxy 创建事务的Aop 代理对象
return proxyFactory.getProxy(this.proxyClassLoader);
}
(f)、最终生成代理对象
5、代理类执行
JdkDynamicAopProxy#invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
// 如果目标方法没有实现equals
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// 如果目标方法没有实现hashcode
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
// 根据代理对象的配置来调用服务
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 获取目标对象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 获取定义好的拦截器链
// 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.
// 没有拦截链则直接调用target方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
//对拦截链进行封装 得到对象ReflectiveMethodInvocation 调用 proceed 方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();// 方法内部将执行拦截器的切面直到目标方法被执行
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
7、代理会执行到: ReflectiveMethodInvocation#proceed 方法
8、最终会执行到:TransactionInterceptor#invoke 方法
9、执行 TransactionAspectSupport 事务方法
TransactionInterceptor#invoke 方法会调用到父类的 TransactionAspectSupport#invokeWithinTransaction 方法
10、业务方法执行
11、Spring 事务处理的流程
(a)、开启事务
(b)、事务回滚
(c)、事务提交