禅与计算机 禅与计算机
首页
  • Java基础

    • JavaScript
  • Java并发编程

    • 《JavaScript教程》
    • 浅谈Java并发安全发布技术
    • 浅谈Java线程池中拒绝策略与流控的艺术
    • 深入源码解析synchronized关键字
    • 浅谈Java并发编程中断的哲学
    • 深入理解Java中的final关键字
    • 深入剖析Java并发编程中的死锁问题
    • 浅谈池化技术的优雅关闭
    • synchronized关键字使用指南
    • 浅谈并发编程等待通知模型
    • 浅谈传统并发编程的优化思路
    • JS设计模式总结
  • JVM相关

    • 从零开始理解JVM的JIT编译机制
    • 简明的Arthas配置及基础运维教程
    • 基于Arthas Idea的JVM故障排查与指令生成
    • 基于arthas量化监控诊断java应用方法论与实践
    • 深入剖析arthas技术原理
    • G1垃圾回收器:原理详解与调优指南
  • 深入理解Spring框架

    • Spring 核心知识点全面解析
    • Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路
    • Spring AOP 深度剖析与实践
  • 计算机组成原理

    • 浅谈CPU流水线的艺术
  • 操作系统

    • Linux性能问题排查最佳实践
    • Linux上IO性能问题的故障排除实践
    • 浅谈Linux权限管理
    • 从操作系统底层浅谈程序栈的高效性
  • 编码最佳实践

    • 浅谈现代软件工程TDD最佳实践
    • 浅谈TDD模式下并发程序设计与实现
    • 面向AI编程新范式Trae后端开发环境搭建与实践
    • 基于提示词工程的Redis签到功能开发实践
    • 基于Vibe Coding的Redis分页查询实现
    • 告别AI无效对话:资深工程师的提示词设计最佳实践
  • 实用技巧与配置

    • Mac常用快捷键与效率插件指南
    • Keynote技术科普短视频制作全攻略
  • 写作

    • 写好技术博客的5大核心原则:从认知科学到AI工具的全流程指南
  • 开发工具

    • IDEA配置详解与高效使用指南
  • Nodejs
  • 博客搭建
  • Spring AI

    • Spring AI Alibaba深度实战:一文掌握智能体开发全流程
    • Spring AI Alibaba实战:JVM监控诊断Arthas Agent的工程化构建与最佳实践
  • 大模型评测

    • M2.7 真能打!我用两个真实场景测了测,结果有点意外
    • Qoder JetBrains插件评测:祖传代码重构与接口优化实战
  • AI IDE评测
  • AI工具链
  • 行业应用
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

sharkchili

计算机禅修者
首页
  • Java基础

    • JavaScript
  • Java并发编程

    • 《JavaScript教程》
    • 浅谈Java并发安全发布技术
    • 浅谈Java线程池中拒绝策略与流控的艺术
    • 深入源码解析synchronized关键字
    • 浅谈Java并发编程中断的哲学
    • 深入理解Java中的final关键字
    • 深入剖析Java并发编程中的死锁问题
    • 浅谈池化技术的优雅关闭
    • synchronized关键字使用指南
    • 浅谈并发编程等待通知模型
    • 浅谈传统并发编程的优化思路
    • JS设计模式总结
  • JVM相关

    • 从零开始理解JVM的JIT编译机制
    • 简明的Arthas配置及基础运维教程
    • 基于Arthas Idea的JVM故障排查与指令生成
    • 基于arthas量化监控诊断java应用方法论与实践
    • 深入剖析arthas技术原理
    • G1垃圾回收器:原理详解与调优指南
  • 深入理解Spring框架

    • Spring 核心知识点全面解析
    • Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路
    • Spring AOP 深度剖析与实践
  • 计算机组成原理

    • 浅谈CPU流水线的艺术
  • 操作系统

    • Linux性能问题排查最佳实践
    • Linux上IO性能问题的故障排除实践
    • 浅谈Linux权限管理
    • 从操作系统底层浅谈程序栈的高效性
  • 编码最佳实践

    • 浅谈现代软件工程TDD最佳实践
    • 浅谈TDD模式下并发程序设计与实现
    • 面向AI编程新范式Trae后端开发环境搭建与实践
    • 基于提示词工程的Redis签到功能开发实践
    • 基于Vibe Coding的Redis分页查询实现
    • 告别AI无效对话:资深工程师的提示词设计最佳实践
  • 实用技巧与配置

    • Mac常用快捷键与效率插件指南
    • Keynote技术科普短视频制作全攻略
  • 写作

    • 写好技术博客的5大核心原则:从认知科学到AI工具的全流程指南
  • 开发工具

    • IDEA配置详解与高效使用指南
  • Nodejs
  • 博客搭建
  • Spring AI

    • Spring AI Alibaba深度实战:一文掌握智能体开发全流程
    • Spring AI Alibaba实战:JVM监控诊断Arthas Agent的工程化构建与最佳实践
  • 大模型评测

    • M2.7 真能打!我用两个真实场景测了测,结果有点意外
    • Qoder JetBrains插件评测:祖传代码重构与接口优化实战
  • AI IDE评测
  • AI工具链
  • 行业应用
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础

  • 并发编程

  • JVM相关

  • 深入理解Spring框架

    • Spring 核心知识点全面解析
    • Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路
    • Spring AOP 深度剖析与实践
      • author: name: sharkchili link: https://github.com/shkctl
      • 写在文章开头
      • 详解Spring对AOP的设计与实现
        • 对AOP的理解
        • 什么是AOP中切点、切面、通知
        • Spring AOP和AspectJ AOP的区别
        • AspectJ 通知类型
        • 多个切面执行顺序我们如何确定
        • AOP操作在bean生命周期的那个阶段实现
        • 动态代理是什么
        • 动态代理的创建过程
      • 详解CGLIB代理
        • Spring AOP和Cglib的关系
        • Cglib代理流程是是什么样的
        • Spring中的Cglib代理流程
      • 详解JDK代理
        • JDK代理示例
        • JDK代理的工作流程
        • Spring AOP中JDK代理的实现
      • 小结
      • 参考
  • Java核心技术
  • 深入理解Spring框架
sharkchili
2026-03-23
目录

Spring AOP 深度剖析与实践


title: Spring AOP 深度剖析与实践 date: 2026-03-23 10:00:00 permalink: /pages/2b8c7d/ categories:

  • Java核心技术
  • 深入理解Spring框架 tags:

# author: name: sharkchili link: https://github.com/shkctl

# 写在文章开头

在当今复杂多变的软件开发领域,Spring 框架无疑是一颗璀璨的明星。而其中的 Spring AOP(面向切面编程)更是以其独特的魅力和强大的功能,为开发者们打开了一扇通往全新编程境界的大门。

当我们深入探索 Spring AOP 的世界,就仿佛置身于一个充满无限可能的编程宇宙之中。它犹如一把神奇的钥匙,能够巧妙地解开代码结构中的复杂症结,让我们可以从全新的切面视角去审视和构建软件。无论是实现系统级的横切关注点,如日志记录、事务管理、安全控制等,还是对业务逻辑进行精细化的分离与整合,Spring AOP 都展现出了无与伦比的适应性和灵活性。它并非仅仅是一种技术手段,更是一种编程理念的革新,为我们带来了高效、简洁且极具扩展性的开发方式。让我们一同踏上这趟精彩的 Spring AOP 之旅,去领略它所蕴含的奥秘与力量。

在这里插入图片描述

Hi,我是 sharkChili ,是个不断在硬核技术上作死的技术人,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili 。

同时也非常欢迎你star我的开源项目mini-redis:https://github.com/shark-ctrl/mini-redis (opens new window)

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

# 详解Spring对AOP的设计与实现

# 对AOP的理解

AOP(Aspect-Oriented Programming:面向切面编程),它实际做的就是将业务和一些非业务进行拆解,降低彼此业务模块与非业务模块的耦合度,便于后续的扩展维护。例如权限校验、日志管理、事务处理等都可以使用AOP实现。而Spring就是基于动态代理实现AOP的。如果被代理的类有实现接口的话,就会基于JDK Proxy完成代理的创建,反之就是通过Cglib完成代理创建,当然你也可以强制使用Cglib。

在这里插入图片描述

# 什么是AOP中切点、切面、通知

AOP中有很多核心术语,分别是:

  1. 目标(Target): 这就被代理的对象,例如我们希望对UserService每个方法进行增强(在不动它的代码情况下增加一些非业务的动作),那么这个UserService就是目标。
  2. 代理(Proxy): 就是给你被代理后的对象的厂商,例如我们上面说过希望对UserService每个方法进行增强,那么给用户返回增强后的对象的类就是代理类。
  3. 连接点(JoinPoint):目标对象,每一个可能可以被增强的方法都可以称为连接点,尽管它最后可能不会被增强。
  4. 切入点(Pointcut): 连接点中即能够应用通知的位置。
  5. 通知(Advice): 不要被表面的语义误导,通知并不是告知某人的意思,通知的意思是拦截对象后,做的增强操作,也就是拦截后要执行什么代码。
  6. 切面(Aspect): 切入点(Pointcut)+通知(Advice)。
  7. 织入(Weaving):把通知的动作融入到对象中,生成代理对象的过程就叫做织入。

在这里插入图片描述

# Spring AOP和AspectJ AOP的区别

Spring AOP属于运行时增强,基于代理(Proxying)实现的。而AspectJ AOP属于编译时增强,基于字节码操作(Bytecode Manipulation)实现的。

在《精通spring4.x》一书中,我们可以知道,jdk生成的代理对象性能远远差于cglib生成代理对象,但cglib创建代理对象花费的时间却远远高于jdk代理创建的对象。所以在spring框架的使用中,如果是单例的bean需要实现aop等操作,我们建议是使用cglib动态代理技术:

# AspectJ 通知类型

  1. Before(前置通知): 目标对象方法调用前触发增强。
  2. After (后置通知):目标对象方法调用后进行增强。
  3. AfterReturning(返回通知):目标对象方法执行结束,返回值时进行增强。
  4. AfterThrowing(异常通知):目标对象方法执行报错并抛出时做的增强。
  5. Around(环绕通知):这个比较常用了,目标对象方法调用前后我们可以做各种增强操作,甚至不调用对象的方法都能做到。

# 多个切面执行顺序我们如何确定

答: 有两种方式:

  1. 注解法:使用@Order注解来决定切面bean的执行顺序。
// 值越小优先级越高
@Order(1)
@Component
@Aspect
public class LoggingAspect implements Ordered {

1
2
3
4
5
6
  1. 继承接口法:implements Ordered接口
@Component
@Aspect
public class LoggingAspect implements Ordered {

    // ....

    @Override
    public int getOrder() {
        // 返回值越小优先级越高
        return 1;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# AOP操作在bean生命周期的那个阶段实现

在bean初始化前后也就我们常说的BPP阶段完成AOP类的缓存以及通知器创建。在bean初始化后,根据需要结合通知器完成代理类的改造。

# 动态代理是什么

是在运行期间,创建目标对象的代理对象,目标对象不变,我们通过对方法动态拦截,进行前置或者后置等各种增强操作。AOP中就有CGLIB动态代理和JDK动态代理技术。

# 动态代理的创建过程

AOP提供了一个默认工厂根据类是否有继承接口或者是否就是目标类决定创建的策略。然后根据不同的策略决定代理类的创建。

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			//如果是接口则走JdkDynamicAopProxy反之走ObjenesisCglibAopProxy
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

以下便是jdk代理的创建策略

@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		.........
	//获取被代理的类的接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

		//生成代理对象并返回
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
1
2
3
4
5
6
7
8
9
10

以下便是cglib的创建策略:

@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
	.......
		try {
		.......
		//将当前类信息通过enhancer 生成代理对象
			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 ClassLoaderAwareGeneratorStrategy(classLoader));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
		//返回最终生成的代理对象
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		........
		}
		catch (Throwable 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

# 详解CGLIB代理

# Spring AOP和Cglib的关系

CGLIB是一个强大、高性能的代码生成包。使用ASM操作字节码,动态生成代理,对方法进行增强。,它广泛的被许多AOP框架使用,为他们提供方法的拦截。

在这里插入图片描述

例如我们希望对某个service进行日志打印,基于CGLIB我们可以这样实现:

前置步骤引入依赖:

  <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
1
2
3
4
5

首先创建用户类

public class User {
    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }


    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

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

service类

public class UserServiceImpl {

    public List<User> findUserList() {
        return Collections.singletonList(new User("xiaoming", 18));
    }
}

1
2
3
4
5
6
7

代理类

public class CglibProxy<T> implements MethodInterceptor {


    private static Logger logger = LoggerFactory.getLogger(CglibProxy.class);

    private Object target;


    public  T getTargetClass(Object target) {
        //设置被代理的目标类
        this.target = target;
        // 创建加强器设置代理类以及回调,当代理类被调用时,callback就会去调用intercept
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        //返回代理类
        return (T) enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        logger.info("调用被代理对象的方法,代理对象:[{}],代理方法:[{}]", o.getClass().getName(), method.getName());
        Object result = methodProxy.invokeSuper(o, args);
        logger.info("代理调用结束,返回结果:[{}]", String.valueOf(result));

        return null;
    }
}

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

测试代码

public class Main {
    public static void main(String[] args) {
        CglibProxy<UserServiceImpl> cglibProxy = new CglibProxy();

        UserServiceImpl targetClass =cglibProxy.getTargetClass(new UserServiceImpl());
        targetClass.findUserList();

    }
}

1
2
3
4
5
6
7
8
9
10

# Cglib代理流程是是什么样的

如下图所示,整体来说就是基于enhancer去配置被代理类的各种参数,然后生成代理类:

注意:final方法无法被代理,因为它不可被子类覆盖。

在这里插入图片描述

# Spring中的Cglib代理流程

源码如下,我们可以看出和我们写的实例代码是差不多的。

@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
.....

		try {
			//获取当前类信息获取生成代理对象
			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 ClassLoaderAwareGeneratorStrategy(classLoader));

		// 获取当前类中的方法
			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// 生成代理对象
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException | IllegalArgumentException ex) {
			.....
		}
		catch (Throwable 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

# 详解JDK代理

# JDK代理示例

答:这个是jdk自带的一种代理,我们只需继承InvocationHandler即可实现。但是前提是这个类必须继承某些接口才能使用jdk代理。

首先我们定义接口,User类沿用上述的

public interface UserService {

    List<User> findUserList();
}

1
2
3
4
5

修改UserServiceImpl

public class UserServiceImpl implements UserService{

    @Override
    public List<User> findUserList() {
        return Collections.singletonList(new User("xiaoming", 18));
    }
}

1
2
3
4
5
6
7
8

jdk代理类

public class JDKProxy<T> {

    private static Logger logger = LoggerFactory.getLogger(JDKProxy.class);

    private Object target;

    public JDKProxy(Object target) {
        this.target = target;
    }


    public T getTargetObj() {
        UserService proxy;
        ClassLoader loader = target.getClass().getClassLoader();
        Class[] interfaces = new Class[]{UserService.class};
        InvocationHandler handler = (p, method, args) -> {
            logger.info("代理方法被调用,类名称[{}],方法名称[{}]", target.getClass().getName(), method.getName());
            Object result = method.invoke(target, args);
            logger.info("代理方法调用结束,返回结果:[{}]", String.valueOf(result));
            return result;
        };

        proxy = (UserService) Proxy.newProxyInstance(loader, interfaces, handler);
        return (T) proxy;
    }


}

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

测试代码

public class Main {
    public static void main(String[] args) {
       
        JDKProxy<UserService> jdkProxy=new JDKProxy<>(new UserServiceImpl());
        UserService userService = jdkProxy.getTargetObj();
        System.out.println(userService.findUserList());
    }
}

1
2
3
4
5
6
7
8
9

# JDK代理的工作流程

我们不妨在jvm在下面这样一段参数,或者在上述main方法加这个代码

 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
1

然后我们通过debug可以发现它回步入这段代码,其中他会生成一个ClassFile,方法名为generateClassFile

public static byte[] generateProxyClass(final String name,
                                        Class<?>[] interfaces,
                                        int accessFlags)
{
    ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
    final byte[] classFile = gen.generateClassFile();
    ...
}

1
2
3
4
5
6
7
8
9

而代理方法做的事情,整体如下所示,可以看到它整体做的就是拿着被代理类的 各种方法封装成ProxyMethod方法,然后写入class文件中:

/**
    * Generate a class file for the proxy class.  This method drives the
    * class file generation process.
    */
private byte[] generateClassFile() {

    /* 第一步:将所有方法包装成ProxyMethod对象 */
    
    // 将Object类中hashCode、equals、toString方法包装成ProxyMethod对象
    addProxyMethod(hashCodeMethod, Object.class);
    addProxyMethod(equalsMethod, Object.class);
    addProxyMethod(toStringMethod, Object.class);

    // 将代理类接口方法包装成ProxyMethod对象
    for (Class<?> intf : interfaces) {
        for (Method m : intf.getMethods()) {
            addProxyMethod(m, intf);
        }
    }

   	//......

    /* 第二步:为代理类组装字段,构造函数,方法,static初始化块等 */
    try {
        // 添加构造函数,参数是InvocationHandler
        methods.add(generateConstructor());

        // 代理方法
        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
            for (ProxyMethod pm : sigmethods) {

                // 字段
                fields.add(new FieldInfo(pm.methodFieldName,
                    "Ljava/lang/reflect/Method;",
                        ACC_PRIVATE | ACC_STATIC));

                // 上述ProxyMethod中的方法
                methods.add(pm.generateMethod());
            }
        }

        // static初始化块
        methods.add(generateStaticInitializer());

    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception", e);
    }
	//......

    /* 第三步:写入class文件 */

  	//......

    try {
  			//......
        dout.writeShort(0); // (no ClassFile attributes for proxy classes)

    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception", e);
    }

    return bout.toByteArray();
}

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

看看上文命令下创建class,可以看到它 implements UserService 以及通过我们的的代理类的InvocationHandler 调用这些方法

public final class $Proxy0 extends Proxy implements UserService {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

   	//......
   	
	//动态代理了findUserList方法,后续调用时本质上是通过代理类的method对原有方法进行调用,即我们的InvocationHandler所实现的逻辑
    public final List findUserList() throws  {
        try {
            return (List)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    	//......
    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            //初始化我们的代理方法类method
            m3 = Class.forName("com.pdai.aop.jdkProxy.UserService").getMethod("findUserList");
            	//......
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
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

# Spring AOP中JDK代理的实现

JdkDynamicAopProxy源码如下,可以看到本质上也是通过传入:

  1. 类加载器
  2. 接口类型,通过proxiedInterfaces获取对应接口到代理缓存中获取要生成的代理类型
  3. 对应的InvocationHandler 进行逻辑增强。
@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
	
	//......
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
1
2
3
4
5
6

# 小结

我是 sharkchili ,CSDN Java 领域博客专家,mini-redis的作者,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili 。

同时也非常欢迎你star我的开源项目mini-redis:https://github.com/shark-ctrl/mini-redis (opens new window)

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

# 参考

Spring 常见面试题总结:https://javaguide.cn/system-design/framework/spring/spring-knowledge-and-questions-summary.html#spring-基础 (opens new window)

Spring进阶 - Spring AOP实现原理详解之AOP切面的实现:https://www.pdai.tech/md/spring/spring-x-framework-aop-source-1.html (opens new window)

Spring进阶 - Spring AOP实现原理详解之AOP代理的创建:https://www.pdai.tech/md/spring/spring-x-framework-aop-source-2.html (opens new window)

Spring进阶 - Spring AOP实现原理详解之Cglib代理实现:https://www.pdai.tech/md/spring/spring-x-framework-aop-source-3.html (opens new window)

Spring进阶 - Spring AOP实现原理详解之JDK代理实现:https://www.pdai.tech/md/spring/spring-x-framework-aop-source-4.html (opens new window)

《spring实战第四版》

编辑 (opens new window)
Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路

← Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路

最近更新
01
Spring 核心知识点全面解析
03-22
02
Qoder JetBrains插件评测:祖传代码重构与接口优化实战
03-22
03
M2.7 真能打!我用两个真实场景测了测,结果有点意外
03-20
更多文章>
Theme by Vdoing | Copyright © 2025-2026 Evan Xu | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×
×