跨境互联网 跨境互联网
首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)

Revin

首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)
  • Spring Data JPA
  • MyBatis

  • Spring

    • Spring高级使用

      • Spring概述
      • Spring核心思想
      • 手写实现 IoC 和 AOP
      • Spring IOC 应用
      • Spring IOC源码深度剖析
      • Spring AOP 应用
      • Spring AOP源码深度剖析
        • 1.1 AOP基础用例准备
        • 1.2 时机点分析
        • 1.3 代理对象创建流程
        • 2.1 @EnableTransactionManagement
        • 2.2 加载事务控制组件
    • Spring源码剖析

    • 资料
  • SpringBoot

  • Jdk

  • Tomcat

  • Netty

  • 若依

  • Traefik

  • Openresty

  • 开源框架
  • Spring
  • Spring高级使用
Revin
2023-07-23
目录

Spring AOP源码深度剖析

# 第1节 代理对象创建

# 1.1 AOP基础用例准备

Bean定义

@Component
public class LagouBean {
  public void tech(){
    System.out.println("java learning......");
  }
}
1
2
3
4
5
6

Aspect定义

package com.lagou;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LagouAspect {
  @Pointcut("execution(* com.lagou.*.*(..))")
  public void pointcut(){
  }
  
  @Before("pointcut()")
  public void before() {
    System.out.println("before method ......");
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

测试用例

/**
测试用例:Aop 代理对象创建
*
*/
@Test
public void testAopProxyBuild(){
  ApplicationContext applicationContext = new  AnnotationConfigApplicationContext(SpringConfig.class);
  LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
  lagouBean.tech();
}
1
2
3
4
5
6
7
8
9
10

# 1.2 时机点分析

Spring高级框架课程笔记_Page79_01

我们发现在 getBean 之前,LagouBean对象已经产生(即在第一行初始化代码中完成),而且该对象

是一个代理对象(Cglib代理对象),我们断定,容器初始化过程中目标Ban已经完成了代理,返回了代

理对象。

# 1.3 代理对象创建流程

AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object,

org.springframework.beans.factory.support.RootBeanDefinition)

  /**
  *
  * 初始化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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Spring高级框架课程笔记_Page81_01

创建代理对象的后置处理器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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

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))) {
      eturn bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(),
    beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
    }
    // Create proxy if we have advice.
    // 得到所有候选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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

AbstractAutoProxyCreator#createProxy

/**
* Create an AOP proxy for the given bean.
* 为指定 bean 创建代理对象
*/
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());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

接着跟进到ProxyFactory中

public class ProxyFactory extends ProxyCreatorSupport {
  public Object getProxy(ClassLoader classLoader) {
      // 用ProxyFactory创建AopProxy, 然后用AopProxy创建Proxy, 所以这里重要的是看获取的AopProxy
      // 对象是什么,
      // 然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
      return createAopProxy().getProxy(classLoader);
  }
}
1
2
3
4
5
6
7
8
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;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

流程就是用AopProxyFactory创建AopProxy, 再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy方法

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()) {
        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<?>[] interfaces = config.getProxiedInterfaces();
      return (interfaces.length == 0 || (interfaces.length == 1 &&
      SpringProxy.class.equals(interfaces[0])));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

这里决定创建代理对象是用JDK Proxy,还是用 Cglib 了,最简单的从使用方面使用来说:设置

proxyTargetClass=true强制使用Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK 代理,如果没有实现接口则也必须用Cglib

ProxyFactory#getProxy(java.lang.ClassLoader)

------ CglibAopProxy#getProxy(java.lang.ClassLoader)

@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);
        // 配置 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);
        // 生成代理类,并且创建一个代理类的实例
        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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

AOP源码分析类方法调用关系课堂讲解过程中记录

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean


调用


org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization


调用


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)


调用


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary


调用


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy (在这一步把委托对象的aop增强和通用拦截进行合并,最终给代理对象)


调用


org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy


调用


org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 第2节 Spring声明式事务控制

声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了

思考:这些注解都做了什么?好神奇!

@EnableTransactionManagement @Transactional

# 2.1 @EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
1
2
3
4
5

@EnableTransactionManagement 注解使用 @Import 标签引入了

TransactionManagementConfigurationSelector类,这个类又向容器中导入了两个重要的组件

Spring高级框架课程笔记_Page88_01

# 2.2 加载事务控制组件

  • AutoProxyRegistrar

AutoProxyRegistrar 类的 registerBeanDefinitions 方法中又注册了一个组件

Spring高级框架课程笔记_Page88_02

进入 AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法

Spring高级框架课程笔记_Page88_03

发现最终,注册了一个叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,而这个类是

AbstractAutoProxyCreator 的子类,实现了 SmartInstantiationAwareBeanPostProcessor 接口

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator


public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator


public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
1
2
3
4
5
6
7

继承体系结构图如下

Spring高级框架课程笔记_Page89_01

它实现了SmartInstantiationAwareBeanPostProcessor,说明这是一个后置处理器,而且跟

spring AOP 开启@EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator实

现的是同一个接口,所以说,声明式事务是 springAOP 思想的一种应用

  • ProxyTransactionManagementConfiguration 组件
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.annotation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.transaction.config.TransactionManagementConfigUtils;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribut
eSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
/**
* {@code @Configuration} class that registers the Spring infrastructure
beans
* necessary to enable proxy-based annotation-driven transaction
management.
*
* @author Chris Beams
* @since 3.1
* @see EnableTransactionManagement
* @see TransactionManagementConfigurationSelector
*/
@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;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

ProxyTransactionManagementConfiguration是一个容器配置类,注册了一个组件

transactionAdvisor,称为事务增强器,然后在这个事务增强器中又注入了两个属性:

transactionAttributeSource,即属性解析器transactionAttributeSource 和 事务拦截器

transactionInterceptor

    • 属性解析器 AnnotationTransactionAttributeSource 部分源码如下

Spring高级框架课程笔记_Page91_01

属性解析器有一个成员变量是annotationParsers,是一个集合,可以添加多种注解解析器

(TransactionAnnotationParser),我们关注 Spring 的注解解析器,部分源码如下

Spring高级框架课程笔记_Page92_01

属性解析器的作用之一就是用来解析@Transaction注解

    • TransactionInterceptor 事务拦截器,部分源码如下

Spring高级框架课程笔记_Page92_02

Spring高级框架课程笔记_Page92_03

  • 上述组件如何关联起来的?

    • 事务拦截器实现了MethodInterceptor接口,追溯一下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来;
    • 构造方法传入PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上面贴的ProxyTransactionManagementConfiguration的源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用set方法注入这两个属性,效果一样。
  • invokeWithinTransaction 方法,部分源码如下(关注1、2、3、4 标注处)

Spring高级框架课程笔记_Page93_01

Spring高级框架课程笔记_Page93_02

声明式事务分析课堂讲解过程中记录

@EnableTransactionManagement 注解
1)通过@import引入TransactionManagementConfigurationSelector类
它的selectImports方法导入了另外两个类:AutoProxyRegistrar和ProxyTransactionManagementConfiguration


2)AutoProxyRegistrar类分析
方法registerBeanDefinitions中,引入了其他类,通过AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)引入InfrastructureAdvisorAutoProxyCreator,它继承了AbstractAutoProxyCreator,是一个后置处理器类


3)ProxyTransactionManagementConfiguration 是一个添加了@Configuration注解的配置类
(注册bean)
注册事务增强器(注入属性解析器、事务拦截器)
属性解析器:AnnotationTransactionAttributeSource,内部持有了一个解析器集合
Set<TransactionAnnotationParser> annotationParsers;
具体使用的是SpringTransactionAnnotationParser解析器,用来解析
@Transactional的事务属性
事务拦截器:TransactionInterceptor实现了MethodInterceptor接口,该通用拦截
会在产生代理对象之前和aop增强合并,最终一起影响到代理对象
TransactionInterceptor的invoke方法中invokeWithinTransaction会触发原有业
务逻辑调用(增强事务)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
上次更新: 2025/04/03, 11:07:08
Spring AOP 应用
Spring架构设计

← Spring AOP 应用 Spring架构设计→

最近更新
01
tailwindcss
03-26
02
PaddleSpeech
02-18
03
whisper
02-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 跨境互联网 | 豫ICP备14016603号-5 | 豫公网安备41090002410995号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式