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 源码刨析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程