首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 事务初始化源码分析

Spring 事务初始化源码分析

作者头像
Java技术编程
修改2020-05-21 12:36:57
4390
修改2020-05-21 12:36:57
举报
文章被收录于专栏:Java技术编程Java技术编程

本文首发于个人公众号 Java 技术大杂烩,欢迎关注

前言

在上篇文章 Spring 事务使用详解 中详细介绍了 Spring 事务的使用过程,今天就来看下 Spring 事务是如何来实现,比如 Spring 事务在初始化的时候做了什么,Spring 事务是如何进行事务的提交和回滚的;为了避免篇幅太长,所以分开两篇文章进行分析,这篇文章先来分析下 Spring 事务是如何初始化的,在初始化的时候做了什么。

注册 InfrastructureAdvisorAutoProxyCreator

我们知道,想要使用 Spring 事务,就得开启 Spring 的事务功能,如果是配置文件的方式,则需要在配置文件中配置 <tx:annotation-driven /> 标签,那么分析 Spring 事务初始化就从解析该标签开始。

TxNamespaceHandler 类的 init 方法中可以看到解析该标签的代码逻辑:

 public class TxNamespaceHandler extends NamespaceHandlerSupport {
    // .......
    @Override
    public void init() {
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }
}

所以,当在解析 <tx:annotation-driven /> 标签的时候,会使用 AnnotationDrivenBeanDefinitionParser 类的 parse 方法来进行解析:

// AnnotationDrivenBeanDefinitionParser.java

public BeanDefinition parse(Element element, ParserContext parserContext) {
    this.registerTransactionalEventListenerFactory(parserContext);
    String mode = element.getAttribute("mode");
    if ("aspectj".equals(mode)) {
        // aspectj 模式
        this.registerTransactionAspect(element, parserContext);
    } else {
        // proxy 模式 
    AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
    }
    return null;
}

接下来看下proxy模式,即默认模式的解析;即用的是它的内部类 AopAutoProxyConfigurerconfigureAutoProxyCreator 方法进行解析:

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    // ...............
}

在该方法中,第一行就是进行注册 InfrastructureAdvisorAutoProxyCreator,还有其他的bean的注册,这里先不管;先来看下注册过程:

public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    // 注册
    BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
            parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 处理proxy-target-class和 expose-proxy属性
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // ......
}

这里和 Spring AOP 的处理流程是一样的,先是注册目标 bean,再处理 proxy-target-classexpose-proxy 属性,可以参考: Spring AOP 注解方式源码解析 (https://my.oschina.net/mengyuankan/blog/2995521)

注册 InfrastructureAdvisorAutoProxyCreator.class
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,Object source) {
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, 
                BeanDefinitionRegistry registry,Object source) {
    // 处理优先级
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }
    // 注册
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

关于该 bean 的作用下面分析,在 AopAutoProxyConfigurerconfigureAutoProxyCreator 方法中除了注册该 bean,还注册了三个bean,这三个 bean 用来支撑 Spring 的整个事务功能:

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    // 注册 InfrastructureAdvisorAutoProxyCreator
    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    // 事务AdvisorBeanName
    String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
    if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
        // 注册 AnnotationTransactionAttributeSource
        Object eleSource = parserContext.extractSource(element);
        RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
        sourceDef.setSource(eleSource);
        sourceDef.setRole(2);
        String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
        // 注册 TransactionInterceptor
        RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
        interceptorDef.setSource(eleSource);
        interceptorDef.setRole(2);
        AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
        interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
        // 注册 BeanFactoryTransactionAttributeSourceAdvisor
        RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
        advisorDef.setSource(eleSource);
        advisorDef.setRole(2);
        // 并把上面注册的两个bean当作该bean的属性
        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);
        // 注册其他的事件通知组件
    }
}

在这里注册的三个 bean:

  • BeanFactoryTransactionAttributeSourceAdvisor
  • AnnotationTransactionAttributeSource
  • TransactionInterceptor

主要是用来执行目标方法,事务的提交和回滚的.

这三个 bean 关系如下:

InfrastructureAdvisorAutoProxyCreator

这个类是什么意思呢?它有什么用呢?按照类名来理解就是 基础的 Advisor 自动代理创建器,对于自定义的 Advisor,则不用它来创建,它的类图如下:

可以看到它实现了 BeanPostProcessor 接口,而在前面分析 Spring 相关源码的时候知道,该接口是 Spring 提供了一个扩展接口,有两个方法:

public interface BeanPostProcessor {
    // bean 初始化之前执行
    default Object postProcessBeforeInitialization(Object bean, String beanName){
        return bean;
    }
    // bean 初始化之后执行
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

所以,当我们定义的一个 bean 初始化完成后,就会执行 postProcessAfterInitialization 方法,而 InfrastructureAdvisorAutoProxyCreator 类实现了该方法:

public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean != null) {
        // 根据 beanClassName 和 beanName 创建一个key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 包装 bean
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

// 包装bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 已经处理过了,直接返回
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 该 bean不需要增强,直接返回
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 是否是Advice.class, Pointcut.class, Advisor.class, AopInfrastructureBean.class 这几个类,如果是
    // 这几个类,或者该bean需要跳过的,则直接返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    // 如果有增强,则创建代理
    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;
}

// 创建代理
protected Object createProxy(Class<?> beanClass, String beanName,
         Object[] specificInterceptors, TargetSource targetSource) {
    // ....
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            // CGLIB 代理
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            // JDK接口代理
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }
    // 创建代理
    return proxyFactory.getProxy(getProxyClassLoader());
}

// 真正创建代理
public Object getProxy(ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
    //.....
    return getAopProxyFactory().createAopProxy(this);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 判断 CGLIB 代理和 JDK 代理的条件
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        // JDK 代理
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        // CGLIB 代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        // JDK 代理
        return new JdkDynamicAopProxy(config);
    }
}

上述的这段代码,当我们的 bean 初始化完成后,就会为该 bean 创建代理,创建代理的时候,根据配置条件创建 JDK 动态代理或者 CGLIB 代理

Spring 代理创建参考: Spring AOP 创建代理的源码解析(https://my.oschina.net/mengyuankan/blog/2995754)

但是,是不是所有的 bean 都会创建代理呢,不是的,在包装 bean 的方法 wrapIfNecessary 中,会去查找该 bean 对应的增强,如果有相应的增强,则才会去创建代理,所以说在创建代理之前,会先去查找该 bean对应的增强(拦截器),在 wrapIfNecessary 方法中有该代码:

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

对于 Spring 事务来说,该方法返回 specificInterceptors 不可能为空,所以才会走后面创建代理的逻辑。 接下来看下该方法的实现过程,即查询对应 class 或 method 的增强器。

查询对应 class 或 method 的增强器

getAdvicesAndAdvisorsForBean方法中,第一步,要找出符合条件的增强器,第二步,需要判断增强器是否符合要求。

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,TargetSource targetSource) {
    // 根据 className 和 beanName 找出符合条件的增强器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

// 找出增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //查找增强器
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //判断增强器是否符合条件
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    //.......
    return eligibleAdvisors;
}
查找增强器 findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
    return this.advisorRetrievalHelper.findAdvisorBeans();
}

public List<Advisor> findAdvisorBeans() {
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 获取所有 Advisor.class 类 
        // 在前面注册的 bean:BeanFactoryTransactionAttributeSourceAdvisor 也是一个 Advisor,
        // 所以,在这里该 bean 会被提取出来,后续一起植入代理
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
       // 判断增强器bean是否符合条件,这里返回true 
       if (isEligibleBean(name)) {
         if (this.beanFactory.isCurrentlyInCreation(name)) {
            //跳过正在创建的增强器
         }
         else {
            advisors.add(this.beanFactory.getBean(name, Advisor.class));
          }
       }
    }
    return advisors;
}

查找所有的增强器,就是查找 Advisor.class 类, 这里要说明一下,在前面注册的bean BeanFactoryTransactionAttributeSourceAdvisor,它也是一个 Advisor,所以在获取所有的 Advisor.class 类的时候,也会把该 bean 提取出来;此外,该 bean还拥有 AnnotationTransactionAttributeSourceTransactionInterceptor 这两个bean,后面会一起被织入代理。

当查找到所有的增强后,需要判断哪些增强符合我们的目标 bean,对应方法 findAdvisorsThatCanApply,判断的标准很简单,就是去目标类的方法中查找是否存在事务注解 @Transactional,如果存在则满足。

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    // 用来存放符合条件的增强
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    // 处理引介增强
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // 在处理引介增强时已经处理过了
            continue;
        }
        // 普通的bean
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

在这里,如果增强器满足我们的目标 bean,则会返回增强,之后会对目标 bean创建代理,并把增强织入到代理中。

判断是否满足,使用 canApply方法进行判断

解析@Transactional

canApply 方法如下:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    if (advisor instanceof IntroductionAdvisor) {
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    else if (advisor instanceof PointcutAdvisor) {
        /// pca=BeanFactoryTransactionAttributeSourceAdvisor
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        //pca.getPointcut()=TransactionAttributeSourcePointcut
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
    else {
        return true;
    }
}

对于一个事务 bean 来说,该增强 Advisor 就是前面注册的 BeanFactoryTransactionAttributeSourceAdvisor,而该 bean 实现了 PointcutAdvisor 接口,所以会通过 第二个 if 判断;之后 通过 getPointcut 得到 TransactionAttributeSourcePointcut 对象继续调用重载的 canApply 方法如下:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    // 获取方法匹配器
    // 此时的匹配器是 TransactionAttributeSourcePointcut
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    // 如果可以匹配所有方法,则不再循环方法进行判断
    if (methodMatcher == MethodMatcher.TRUE) {
        return true;
    }
    // 存放目标类和目标类所有的接口
    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    // 遍历目标类和目标类所有的接口下的方法,
    // 如果有任何一个方法能够符合增强器的要求,即有@Transactional注解,则直接返回
    for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      for (Method method : methods) {
        if (introductionAwareMethodMatcher != null ? 
          introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
          // 匹配方法是否满足条件
           methodMatcher.matches(method, targetClass)) {
        return true;
        }
      }
    }
    return false;

到这里,只看到了根据方法去判断是否符合增强器,没有根据类来和接口判断,因为事务注解 @Transactional 可以放在类或接口上,对其下的所有 public方法有用;其实,对类和接口的判断条件在是在matcher 方法里面,调用的使用 TransactionAttributeSourcePointcutmathcer 方法如下:

public boolean matches(Method method, Class<?> targetClass) {
    // .....
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

这里判断是否满足条件,就是对应的方法上是否有 @Transactional 注解。 这里的 tas 就是 AnnotationTransactionAttributeSource,即在文章开头注册的那三个 bean 之一,它的 getTransactionAttribute 如下,去获取事务属性:

public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
    // 忽略 Object 的方法
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }
    // 根据method和class来创建key
    Object cacheKey = getCacheKey(method, targetClass);
    // 根据key查询事务,
    TransactionAttribute cached = this.attributeCache.get(cacheKey);
    if (cached != null) {
       //...
       // 已经判断过了
       return cached;
    }
    else {
       TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
       //....
       return txAttr;
    }
}

computeTransactionAttribute 方法如下:

protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
    // 不是public方法,则跳过
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }
    // 实现类的方法
    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

    // 首先在实现类的方法上查询注解,查询到,则直接返回
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
        return txAttr;
    }

    // 如果在实现类对应方法上找不到注解,则在方法的实现类上查找注解,找到直接返回
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        return txAttr;
    }
    // 存在接口
    if (specificMethod != method) {
        // 在接口方法上查找注解,找到直接返回
        txAttr = findTransactionAttribute(method);
        if (txAttr != null) {
            return txAttr;
        }
        // 如果在接口方法上找不到注解,则在接口上查找注解
        txAttr = findTransactionAttribute(method.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }
    }
    return null;
}

在上述的 computeTransactionAttribute 方法中,可以看到,去查找是一个事务方法上的注解,首先在实现类的方法上查找,找到直接返回,如果还找不到,则在实现类上查找注解;如果在实现类上找不到,再到接口上的方法里面去找,如果接口方法还找不到,则再接口上查找;所以,在这里可以看到,放在类或接口上事务注解可以作用于其下的所有 public 方法,且 方法上的事务注解要优先于类或接口上的注解,即如果再类,接口和方法上都加上事务注解,则会以方法上的注解为准,其次是 类,最后才是接口。

之后,就是去解析注解的属性,对应方法为:findTransactionAttribute:

protected TransactionAttribute findTransactionAttribute(Method method) {
    return determineTransactionAttribute(method);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    // 事务注解解析器
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

// 方法上获取 Transactional 注解
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    // 在方法上获取 Transactional 注解
    AnnotationAttributes attributes =
        AnnotatedElementUtils.findMergedAnnotationAttributes(element, Transactional.class, false, false);
    if (attributes != null) {
        // 解析 Transactional 注解属性
        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;
}

在这里就可以看到,事务注解 @Transactional 的各种各样的属性了。

当然,到这里还没有完;到这里,可以从下往上看下所有的代码,当方法存在 @Transactional注解的时候,该方法就会满足增强器 BeanFactoryTransactionAttributeSourceAdvisor ,之后就会为我们的目标 bean 创建代理,并把增强器 BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中,进而来影响我们的业务逻辑。

总结

这篇文章主要介绍了 Spring 事务的初始化功能,在 Spring 加载的时候,会注册 InfrastructureAdvisorAutoProxyCreator bean,而该 bean 又实现了 BeanPostProcessor 接口,所以当目标bean在初始化完成后,会执行 postProcessAfterInitialization 方法,在该方法中,会去遍历我们的目标 bean 中的方法,如果方法上有 @Transactional事务注解,则会为目标 bean 创建代理,并把 增强器 BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中;当然,BeanFactoryTransactionAttributeSourceAdvisor 还拥有 AnnotationTransactionAttributeSourceTransactionInterceptor 这两个 bean 会一起被织入代理。

所以在 Spring事务初始化的过程中,主要注册了四个 bean

  • InfrastructureAdvisorAutoProxyCreator
  • BeanFactoryTransactionAttributeSourceAdvisor
  • AnnotationTransactionAttributeSource
  • `TransactionInterceptor`

InfrastructureAdvisorAutoProxyCreator 主要是用来查找方法,类或者接口上的事务注解 @Transactional,如果存在注解,则为目标 bean 创建代理,并把其他的三个 bean 织入到代理中,而另外的三个 bean 主要是用来 执行目标方法,进行事务的提交和回滚。

BeanFactoryTransactionAttributeSourceAdvisor

关于使用 BeanFactoryTransactionAttributeSourceAdvisorAnnotationTransactionAttributeSourceTransactionInterceptor 来执行目标方法,提交事务,回滚事务,则在下一篇文章中分析。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java技术大杂烩 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 注册 InfrastructureAdvisorAutoProxyCreator
    • 注册 InfrastructureAdvisorAutoProxyCreator.class
    • InfrastructureAdvisorAutoProxyCreator
    • 查询对应 class 或 method 的增强器
      • 查找增强器 findCandidateAdvisors
      • 解析@Transactional
      • 总结
      • BeanFactoryTransactionAttributeSourceAdvisor
      相关产品与服务
      云顾问
      云顾问(Tencent Cloud Smart Advisor)是一款提供可视化云架构IDE和多个ITOM领域垂直应用的云上治理平台,以“一个平台,多个应用”为产品理念,依托腾讯云海量运维专家经验,助您打造卓越架构,实现便捷、灵活的一站式云上治理。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档