Spring AOP 源码刨析
2022/1/25 12:34:40
本文主要是介绍Spring AOP 源码刨析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
- 一、源码前准备
- 1、AOP 基础用例准备
- 1)Bean 定义
- 2)Aspect 定义
- 3)测试类 用例
- 4)源码时机点分析
- 二、代理对象创建流程
- 1、AbstractAutowireCapableBeanFactory#initializeBean
- 2。AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
- 3、创建代理对象的后置处理器 AbstractAutoProxyCreator#postProcessAfterInitialization
- 4、AbstractAutoProxyCreator#wrapIfNecessary
- 5、AbstractAutoProxyCreator#createProxy
- 6、跟进到 ProxyFactory 中
- 7、ProxyCreatorSupport 中相关
- 8、DefaultAopProxyFactory 类中相关
- 9、ProxyFactory#getProxy --- CglibAopProxy#getProxy
- 10、aop 动态代理 时序图
- 三、Spring 声明式事务控制
- 1、@EnableTransactionManagement
- 2、TransactionManagementConfigurationSelector
- 3、加载事务控制组件 AutoProxyRegistrar
- 4、进入 AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法
- 5、加载事务控制组件 ProxyTransactionManagementConfiguration
- 6、属性解析器 AnnotationTransactionAttributeSource 部分源码。
- 7、关注 Spring 的注解解析器,部分源码。
- 8、TransactionInterceptor 事务拦截器,部分源码。
- 9、TransactionInterceptor#invokeWithinTransaction
一、源码前准备
1、AOP 基础用例准备
1)Bean 定义
@Component public class LagouBean { public void tech(){ System.out.println("java learning......"); } }
2)Aspect 定义
@Component @Aspect public class LagouAspect { @Pointcut("execution(* com.lagou.*.*(..))") public void pointcut(){ } @Before("pointcut()") public void before() { System.out.println("before method ......"); } }
3)测试类 用例
/** * 测试用例:Aop 代理对象创建 */ @Test public void testAopProxyBuild(){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class); LagouBean lagouBean = applicationContext.getBean(LagouBean.class); lagouBean.tech(); }
4)源码时机点分析
我们发现在 getBean 之前,LagouBean 对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib 代理对象),我们断定,容器初始化过程中目标 Bean 已经完成了代理,返回了代理对象。
二、代理对象创建流程
提示:如果有还不熟悉 Spring IoC 源码的朋友请优先查看 Spring IoC 源码刨析 。
1、AbstractAutowireCapableBeanFactory#initializeBean
/** * 初始化 Bean * 包括 Bean 后置处理器初始化 * Bean 的一些初始化方法的执行 init-method * Bean 的实现的声明周期相关接口的属性注入 */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 执行所有的 AwareMethods if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 执行所有的 BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 这里就开始执行 afterPropertiesSet(实现了 InitializingBean 接口)方法和 initMethod invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 整个 Bean 初始化完成,执行后置处理器方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
2。AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@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; }
BeanPostProcessor 为创建代理对象,跟踪断点如下:
3、创建代理对象的后置处理器 AbstractAutoProxyCreator#postProcessAfterInitialization
/** * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * @see #getAdvicesAndAdvisorsForBean */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { // 检查下该类是否已经暴露过了(可能已经创建了,比如 A 依赖 B 时,创建 A 时候,就会先去创建 B。 // 当真正需要创建 B 时,就没必要再代理一次已经代理过的对象),避免重复创建。 Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
4、AbstractAutoProxyCreator#wrapIfNecessary
/** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * @param bean the raw bean instance * @param beanName the name of the bean * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // targetSourcedBeans 包含,说明前面创建过 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; } // Create proxy if we have advice. // 查找出和当前 bean 匹配的 advisor // 得到所有候选 Advisor,对 Advisors 和 bean 的方法双层遍历匹配, // 最终得到一个 List<Advisor>,即specificInterceptors 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; }
5、AbstractAutoProxyCreator#createProxy
/** * Create an AOP proxy for the given bean. * 为指定 bean 创建代理对象 * @param beanClass the class of the bean * @param beanName the name of the bean * @param specificInterceptors the set of interceptors that is * specific to this bean (may be empty, but not null) * @param targetSource the TargetSource for the proxy, * already pre-configured to access the bean * @return the AOP proxy for the bean * @see #buildAdvisors */ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 创建代理的工作交给 ProxyFactory ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); // 根据一些情况判断是否要设置 proxyTargetClass 为 true if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 把增强和通用拦截器对象合并,都适配成 Advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // 设置参数 proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 准备工作做完就开始创建代理 return proxyFactory.getProxy(getProxyClassLoader()); }
6、跟进到 ProxyFactory 中
public class ProxyFactory extends ProxyCreatorSupport { public Object getProxy(@Nullable ClassLoader classLoader) { // 用 ProxyFactory 创建 AopProxy,然后用 AopProxy 创建 Proxy, // 所以这里重要的是看获取的 AopProxy。 // 对象是什么, // 然后进去看怎么创建动态代理,提供了两种:jdk proxy,cglib return createAopProxy().getProxy(classLoader); } }
7、ProxyCreatorSupport 中相关
public class ProxyCreatorSupport extends AdvisedSupport { private AopProxyFactory aopProxyFactory; public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // 先获取创建 AopProxy 的工厂, 再由此创建 AopProxy return getAopProxyFactory().createAopProxy(this); } public AopProxyFactory getAopProxyFactory() { return this.aopProxyFactory; } }
流程就是用 AopProxyFactory 创建 AopProxy,再用 AopProxy 创建代理对象,这里的 AopProxyFactory 默认是DefaultAopProxyFactory,下面看他的 createAopProxy 方法。
8、DefaultAopProxyFactory 类中相关
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException( + "TargetSource cannot determine target class: " + "Either an interface or a target is required " + "for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } /** * Determine whether the supplied {@link AdvisedSupport} has only the * {@link org.springframework.aop.SpringProxy} interface specified * (or no proxy interfaces specified at all). */ private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } }
这里决定创建代理对象是用 JDK Proxy,还是用 Cglib 了,最简单的从使用方面使用来说:设置 proxyTargetClass=true 强制使用 Cglib 代理,什么参数都不设并且对象类实现了接口则默认用 JDK 代 理,如果没有实现接口则也必须用 Cglib。
9、ProxyFactory#getProxy — CglibAopProxy#getProxy
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); } try { Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating " + "a CGLIB proxy"); Class<?> proxySuperClass = rootClass; if (ClassUtils.isCglibProxyClass(rootClass)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer... // 配置 Cglib 增强 Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. // 生成代理类,并且创建一个代理类的实例 return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem " + "include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } }
10、aop 动态代理 时序图
三、Spring 声明式事务控制
声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了。
@EnableTransactionManagement @Transactional
1、@EnableTransactionManagement
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { }
@EnableTransactionManagement 注解使用 @Import 标签引入了 TransactionManagementConfigurationSelector 类。
2、TransactionManagementConfigurationSelector
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { @Override 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; } } }
TransactionManagementConfigurationSelector 类又向容器中导入了两个重要的组件。
3、加载事务控制组件 AutoProxyRegistrar
AutoProxyRegistrar 类的 registerBeanDefinitions 方法中又注册了一个组件。
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; Set<String> 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; } } } } // 代码略。。 } }
4、进入 AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法
@Nullable public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAutoProxyCreatorIfNecessary(registry, null); } @Nullable public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); }
发现最终,注册了一个叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,而这个类是 AbstractAutoProxyCreator 的子类,实现了 SmartInstantiationAwareBeanPostProcessor 接口。
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
它的继承体系结构图如下:
它实现了 SmartInstantiationAwareBeanPostProcessor,说明这是一个后置处理器,而且跟 spring AOP 开启 @EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator 实现的是同一个接口,所以说,声明式事务是 springAOP 思想的一种应用。
5、加载事务控制组件 ProxyTransactionManagementConfiguration
@Configuration public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { // 事务增强器 BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor(); // 向事务增强器中注入 属性解析器 transactionAttributeSource advisor.setTransactionAttributeSource(transactionAttributeSource()); // 向事务增强器中注入 事务拦截器 transactionInterceptor advisor.setAdvice(transactionInterceptor()); if (this.enableTx != null) { advisor.setOrder(this.enableTx.<Integer>getNumber("order")); } return advisor; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) // 属性解析器 transactionAttributeSource public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) // 事务拦截器 transactionInterceptor public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) { interceptor.setTransactionManager(this.txManager); } return interceptor; } }
ProxyTransactionManagementConfiguration 是一个容器配置类,注册了一个组件。
transactionAdvisor,称为事务增强器,然后在这个事务增强器中又注入了两个属性:
即属性解析器 transactionAttributeSource 和事务拦截器 transactionInterceptor。
6、属性解析器 AnnotationTransactionAttributeSource 部分源码。
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable { private static final boolean jta12Present; private static final boolean ejb3Present; static { ClassLoader classLoader = AnnotationTransactionAttributeSource.class .getClassLoader(); jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader); ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader); } private final boolean publicMethodsOnly; // 注解解析器集合 private final Set<TransactionAnnotationParser> annotationParsers; }
属性解析器有一个成员变量是 annotationParsers,是一个集合,可以添加多种注解解析器(TransactionAnnotationParser)。
7、关注 Spring 的注解解析器,部分源码。
SpringTransactionAnnotationParser#parseTransactionAnnotation(TransactionAnnotationParser 子类 SpringTransactionAnnotationParser)
@Override @Nullable public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) { AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( element, Transactional.class, false, false); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } } // 解析对应 @Transactional 的属性 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; }
8、TransactionInterceptor 事务拦截器,部分源码。
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable { // 构造方法传入 public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) { setTransactionManager(ptm); setTransactionAttributes(attributes); } //添加事务支持 @Override @Nullable 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, invocation::proceed); } }
上述组件如何关联起来的?
- 事务拦截器实现了 MethodInterceptor 接口,追溯一下上面提到的 InfrastructureAdvisorAutoProxyCreator 后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个 TransactionInterceptor,这就把这两个组件联系起来;
- 构造方法传入 PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上面贴的 ProxyTransactionManagementConfiguration 的源码, 在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用 set 方法注入这两个属性,效果一样。
9、TransactionInterceptor#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. // 获取属性解析器, // 即在 ProxyTransactionManagementConfiguration 容器配置类中注册事务拦截器时注入的 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)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, 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 //(获取事务管理器,执行回滚操作) completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } // 如果目标方法正常运行,则会执行 commitTransactionAfterReturning // (获取事务管理器,执行提交事务操作) commitTransactionAfterReturning(txInfo); return retVal; } // 代码略。。 }
文章内容输出来源:拉勾教育Java高薪训练营;
这篇关于Spring AOP 源码刨析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南