传播特性
REQUIRED
当前方法存在事务时,子方法加入该事务。此时父子方法共用一个事务,无论父子方法哪个发生异常回滚,整个事务都回滚。即使父方法捕捉了异常,也是会回滚。而当前方法不存在事务时,子方法新建一个事务。
REQUIRES_NEW
无论当前方法是否存在事务,子方法都新建一个事务。此时父子方法的事务时独立的,它们都不会相互影响。但父方法需要注意子方法抛出的异常,避免因子方法抛出异常,而导致父方法回滚
NESTED
当前方法存在事务时,子方法加入在嵌套事务执行。当父方法事务回滚时,子方法事务也跟着回滚。当子方法事务发送回滚时,父事务是否回滚取决于是否捕捉了异常。如果捕捉了异常,那么就不回滚,否则回滚。
SUPPORTS
如果当前上下文中存在事务,那么加入该事务;否则用非事务方式执行
MANDATORY
当前方法必须要在有事务方法中运行,不然就抛出异常;如果有事务,就加入当前事务
NOT_SUPPORTED
如果当前上下文中存在事务,则挂起事务,新方法在没有事务的环境中执行
NEVER
当前方法不应该运行在事物中,如果有事务就抛出异常
源码
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
/**
* 解析 <tx:annotation-driven/> 标签
*/
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
}
else {
// mode="proxy"
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 注册 InfrastructureAdvisorAutoProxyCreator
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// 注册 AnnotationTransactionAttributeSource
// 用来找 Transaction 注解
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// 注册 TransactionInterceptor
// 事务拦截器,执行方法时,开启事务/回滚事务/提交事务
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);
// 注册 BeanFactoryTransactionAttributeSourceAdvisor
// BeanFactoryTransactionAttributeSourceAdvisor 又是一个 PointcutAdvisor ,有一个切入点 TransactionAttributeSourcePointcut
// TransactionAttributeSourcePointcut 用来匹配方法
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);
}
}
}
}
InfrastructureAdvisorAutoProxyCreator
的祖父类AbstractAutoProxyCreator
,实现了postProcessAfterInitialization
方法,在 Bean 初始化后,会调用postProcessAfterInitialization
方法用来创建代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// cacheKey就是beanName或者beanClass
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 需要的话就使用动态代理产生代理对象
// bean : 目标对象
// beanName :目标对象名称
// cacheKey:就是beanName或者beanClass
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;
}
// isInfrastructureClass方法:Advice/Pointcut/Advisor/AopInfrastructureBean接口的beanClass不代理
// shouldSkip方法:对beanName为.ORIGINAL结尾的bean不做代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 查找合适的Advisor(增强器)
// 第一步:找到候选的Advisor,这里我们讲的是 Transactional,所以找到的是前面注册的 BeanFactoryTransactionAttributeSourceAdvisor
// 第二步:找到合适的Advisor,BeanFactoryTransactionAttributeSourceAdvisor 又是一个 PointcutAdvisor ,有一个切入点 TransactionAttributeSourcePointcut ,通过 ClassFilter 和 MethodMatcher 来判断是否是合适 Advisor 。
// 这里的 ClassFilter 是 ClassFilter.TRUE ,永远返回 TRUE
// 这里的 MethodMatcher 其实也是 TransactionAttributeSourcePointcut ,调用 matches 方法其实会调用之前注册的 AnnotationTransactionAttributeSource
// 有兴趣的小伙伴可以跟一下源码
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 对相应的advisor不为空才采取代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 通过jdk动态代理或者cglib动态代,产理生代理对象
// 第三步:针对目标对象产生代理对象
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;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 略。。。
// 获取使用JDK动态代理或者cglib动态代理产生的对象
return proxyFactory.getProxy(getProxyClassLoader());
}
}
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
}
createAopProxy()
返回有CglibAopProxy
和JdkDynamicAopProxy
,分别是 Cglib 代理和 JDK 动态代理。我们这里看 JDK 动态代理。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
// 获取完整的代理接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 调用JDK动态代理方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
JdkDynamicAopProxy
也是一个InvocationHandler
,当执行代理对象的方法时,就会执行JdkDynamicAopProxy#invoke
方法。继续跟JdkDynamicAopProxy#invoke
发现会拿到TransactionInterceptor
,并执行invoke
方法。我们主要看一下TransactionInterceptor#invoke
方法
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}
invokeWithinTransaction
是父类的方法
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
// 事务注解属性对象
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 创建事务并返回事务对象信息
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try {
// 执行下一个拦截器,最终会执行连接点的方法()
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 事务回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清除事务信息
cleanupTransactionInfo(txInfo);
}
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
// 略。。。
}
}
}
标签:事务,beanName,return,Spring,Object,bean,方法
From: https://www.cnblogs.com/back-garden/p/16863210.html