Spring中的AOP和动态代理

简介: Spring 除 IoC 容器外的另一个核心功能是 AOP,面向切面编程是对编程结构的另一种思考。


一、概述



AOP 提供一种通用的扩展机制,在业务操作前后提供一些切面的操作,这些操作通常是和业务无关的,例如:日志记录、性能统计、安全控制、事务处理、异常处理等。


1. AOP 术语


AOP(Aspect Oriented Programming)面向切面编程的概念比较抽象,主要涉及下面这些术语:

  • Aspect(切面):切入一个或多个类的模块
  • Join point(连接点):程序执行的节点,例如执行方法或处理异常
  • Advice(通知):切面在连接点执行的动作,例如前置通知
  • Pointcut(切点):用于匹配连接点,一般通过表达式匹配
  • Target object(目标对象):被切入的对象,可以被一个或多个切面切入

使用 AOP 时,需要定义实现切面的类,在切面中指定切点和通知。微信图片11.png一个目标类可以被多个切面切入,多个切面也可以切入一个目标类。

切面实现的本质是一个或多个基于连接点的拦截器。


2. 通知类型


Spring AOP 提供了下面五种通知类型:

  • Before advice(前置通知):连接点前面执行,不能终止后续流程,除非抛异常
  • After returning advice(后置通知):连接点正常返回时执行,有异常不执行
  • Around advice(环绕通知):围绕连接点前后执行,也能捕获处理异常
  • After advice(最终通知):连接点退出时执行,无论是正常退出还是异常退出
  • After throwing advice(异常通知):连接点方法抛出异常时执行

AOP 的连接点一般是指目标类的方法,五种通知类型执行的节点如下:

微信图片12.png


二、动态代理



Spring AOP 底层是基于动态代理实现的,对实现接口的类进行代理,默认使用 JDK 动态代理,对没实现接口的类,使用 CGLIB 动态代理。

微信图片13.png


1. JDK 动态代理


JDK 动态代理通过实现接口生成代理类,使用拦截器加反射机制生成。

public static void main(String[] args) {
    // JDK Proxy
    DemoService demoService = new DemoServiceImpl();
    DemoServiceProxy proxy = new DemoServiceProxy();
    DemoService proxyTarget = (DemoService) proxy.getTarget(demoService);
    proxyTarget.doService();
}


2. CGLIB 动态代理


CGLIB 动态代理通过继承生成代理子类,使用字节码技术生成。

通过子类对父类的方法进行重写来实现代理,因此,对 final 修饰的方法不能代理。

public static void main(String[] args) {
    // CGLib Proxy
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(DemoServiceImpl.class);
    enhancer.setCallback(new DemoServiceInterceptor());
    DemoService service = (DemoService) enhancer.create();
    service.doService();
}

强制使用 CGLIB 代理

Spring AOP 中的目标类不管有没有实现接口,都可以通过配置来强制使用 CGLIB 代理方式。

基于 XML 配置:

<aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
</aop:config>
<!-- 或者 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

基于注解配置:

@EnableAspectJAutoProxy(proxyTargetClass = true)


三、附录



示例代码


Gitee 仓库:

https://gitee.com/code_artist/spring

项目模块:

spring-aop

示例路径:

cn.codeartist.spring.aop.proxy


目录
相关文章
|
5天前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
|
13天前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
56 8
|
2月前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
2月前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
96 5
|
2月前
|
Java 开发者 Spring
深入解析:Spring AOP的底层实现机制
在现代软件开发中,Spring框架的AOP(面向切面编程)功能因其能够有效分离横切关注点(如日志记录、事务管理等)而备受青睐。本文将深入探讨Spring AOP的底层原理,揭示其如何通过动态代理技术实现方法的增强。
91 8
|
2月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
2月前
|
XML 监控 安全
深入调查研究Spring AOP
【11月更文挑战第15天】
53 5
|
2月前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
59 4
|
2月前
|
安全 Java 开发者
AOP中的JDK动态代理与CGLIB动态代理:深度解析与实战模拟
【11月更文挑战第21天】面向切面编程(AOP,Aspect-Oriented Programming)是一种编程范式,它通过将横切关注点(cross-cutting concerns)与业务逻辑分离,以提高代码的可维护性和可重用性。在Java开发中,AOP的实现离不开动态代理技术,其中JDK动态代理和CGLIB动态代理是两种常用的方式。本文将从背景、历史、功能点、业务场景、底层逻辑等多个维度,深度解析这两种代理方式的区别,并通过Java示例进行模拟和比较。
125 5
|
3月前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
61 3
Spring高手之路23——AOP触发机制与代理逻辑的执行