悦书阁 悦书阁
首页
学习笔记
技术文档
idea插件开发
更多
  • 分类
  • 标签
  • 归档

Felix

大道至简 知易行难
首页
学习笔记
技术文档
idea插件开发
更多
  • 分类
  • 标签
  • 归档
  • JVM

  • spring

    • Spring Bean 生命周期:从源码到实战
    • Spring Aop
      • 动态代理
        • JDK动态代理实现
        • CGLIB动态代理实现
      • Spring AOP
      • Spring事务基本执行原理
      • Spring事务传播机制
    • Spring循环依赖
    • Spring常见问题
  • 并发编程

  • 消息中间件

  • 微服务

  • 三高架构

  • 学习笔记
  • spring
liufei379
2022-06-28
目录

Spring Aop

# 动态代理

说到Spring AOP就先需要了解动态代理。

代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。

实现动态代理的方式有2种:

​ JDK动态代理(只能代理接口类)

​ CGLIB(基于父子类实现)

# JDK动态代理实现

public interface UserInterface {
 	public void test();
}

public class UserService implements UserInterface {
 @Override   
 public void test() {
  	System.out.println("test...");
 }
}

public class Test {

    public static void main(String[] args) {
        
        UserService target = new UserService();
        // UserInterface接口的代理对象
        // 所以产生的代理对象的类型是UserInterface,而不是UserService。
        Object proxy = Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserInterface.class}, (proxy1, method, args1) -> {
            System.out.println("before...");
            Object result = method.invoke(target, args1);
            System.out.println("after...");
            return result;
        });
        UserInterface userService = (UserInterface) proxy;
        userService.test();
    }
}
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

# CGLIB动态代理实现

public class UserService  {

 public void test() {
  	System.out.println("test...");
 }
}

public class Test {

    public static void main(String[] args) {
        UserService target = new UserService();

        // 通过cglib技术
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);

        // 定义额外逻辑,也就是代理逻辑
        enhancer.setCallbacks(new Callback[]{(MethodInterceptor) (o, method, objects, methodProxy) -> {
            System.out.println("before...");
            Object result = methodProxy.invoke(target, objects);
            System.out.println("after...");
            return result;
        }});

        // 动态代理所创建出来的UserService对象
        UserService userService = (UserService) enhancer.create();

        // 执行这个userService的test方法时,就会额外会执行一些其他逻辑
        userService.test();
    }
}
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

# Spring AOP

spring对于以上的两种代理方式进行了分装,封装出来的类叫做ProxyFactory。

通过ProxyFactory,我们可以不再关心到底是用cglib还是jdk动态代理,ProxyFactory会帮我们自动选择,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术,上面的代码,就是由于UserService实现了UserInterface接口,所以最后产生的代理对象是UserInterface类型。(Spring Boot 2.X默认使用CGLIB,即使实现接口也是使用CGLIB)

# Spring事务基本执行原理

开启Spring事务本质上就是增加了一个Advisor,使用@EnableTransactionManagement注解来开启Spring事务。

在spring初始化后的步骤,判断Bean的类上是否存在@Transactional注解,或者类中的某个方法上是否存在@Transactional注解,如果存在则表示该Bean需要进行动态代理产生一个代理对象作为Bean对象。执行基本流程为:

1. 利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接
2. 修改数据库连接的autocommit为false
3. 执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql
4. 如果没有抛异常,则提交
5. 如果抛了异常,则回滚
1
2
3
4
5

# Spring事务传播机制

假设有a,b 2个方法,2个方法都在事务中执行,且b方法开启了新事务,a方法调用b方法,那么大致流程如下:

1.通过AOP,利用事务管理器开启事务a连接,
2.设置手动提交(autocommit = false)
3.将事务a连接放入ThreadLocal中
4.执行a方法中的SQL逻辑
5.a方法调用b方法
6.a方法调用b方法时,由于b方法开启了新的事务,则 将a连接挂起放入挂起资源中,并从ThreadLocal移除事务a连接
7.利用事务管理器开启b事务连接
8.设置手动提交(autocommit = false)
9.将事务b连接放入ThreadLocal中
10.执行b方法的sql,并执行完b方法
11.利用ThreadLocal中的b连接提交事务
12.再把挂起资源中的a连接设置到ThreadLocal中.
13.a方法执行完成之后 利用ThreadLocal中的a连接提交事务
1
2
3
4
5
6
7
8
9
10
11
12
13

:::waring

​ 虽然a和b方法属于2个事务,但是如果b方法执行失败,a方法还是会回滚

:::

上次更新: 2026/3/11 21:47:04
Spring Bean 生命周期:从源码到实战
Spring循环依赖

← Spring Bean 生命周期:从源码到实战 Spring循环依赖→

最近更新
01
实现idea开发的关键步骤
10-05
02
Redis高可用架构
09-09
03
Zookeeper高可用
08-31
更多文章>
Theme by Vdoing | Copyright © 2022-2026 Felix | 粤ICP备17101757号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式