Java AOP Framework概述
Java AOP Framework概述
- 1. AspectJ
- 1.1 使用AspectJ进行切面编程
- 2. Spring AOP
- 2.1 使用Spring AOP进行切面编程
- 2.2 如何决定使用哪种动态代理
- 2.3 如何通过配置指定代理方式
- 2.4 Spring AOP和AspectJ的关系
- 3. Spring Boot AOP
- 4. 扩展
- 4.1 AspectJ织入方式详解
- 参考
Java常用的AOP框架有AspectJ、Spring AOP、Javassist、Guice、Byte Buddy等;本文主要介绍AspectJ的功能示例,Spring AOP的主要功能、代码示例、以及自动代理的配置和实现。并简要介绍了Spring AOP和AspectJ的关系,以及Spring AOP在Spring Boot自动配置时不同版本的差异。
1. AspectJ
AspectJ是一个基于Java语言的强大的面向切面编程(AOP)框架。它扩展了Java语言,提供了更丰富的AOP功能,并且与Java语言紧密集成。
AspectJ提供了一种在编译时或运行时织入切面逻辑的方式,以实现横切关注点的处理。它支持在方法调用、方法执行、字段访问和异常处理等连接点上应用切面逻辑。
以下是AspectJ的一些主要特点和功能:
-
丰富的切入点表达式:AspectJ提供了灵活且强大的切入点表达式语言,可以精确地选择要应用切面的连接点。
-
多种类型的通知:AspectJ支持多种类型的通知,包括前置通知、后置通知、返回通知、异常通知和环绕通知。这些通知可以在切点的不同阶段执行切面逻辑。
-
切面继承和优先级:AspectJ支持切面之间的继承关系和优先级设置,可以灵活地组织和管理切面。
-
静态织入和动态织入:AspectJ支持在编译时进行静态织入,以及在运行时通过字节码增强进行动态织入。这使得切面逻辑可以在不同的阶段应用到目标代码中。
-
强大的切面编程能力:AspectJ提供了丰富的切面编程能力,包括引入新的成员变量和方法到目标类中,修改现有的类和方法,以及对切点进行动态绑定等。
-
与Spring集成:AspectJ与Spring框架紧密集成,可以与Spring AOP无缝协作,提供更强大的AOP功能。
总体而言,AspectJ是一个功能强大且灵活的AOP框架,可以帮助开发人员更好地实现横切关注点的处理。它提供了丰富的特性和语法,使得切面编程变得更加简单和直观。无论是在JavaEE应用程序还是在Spring应用程序中,AspectJ都是一个非常有用的工具。
1.1 使用AspectJ进行切面编程
下面是一个逐步指南,介绍如何使用AspectJ进行切面编程:
-
添加AspectJ依赖:在项目的构建文件(如Maven的pom.xml或Gradle的build.gradle)中添加AspectJ的依赖项。
-
定义切面类:创建一个Java类,用于定义切面逻辑。可以使用
@Aspect
注解来标识该类为切面类。
import org.aspectj.lang.annotation.Aspect;@Aspect
public class MyAspect {// 切面逻辑代码
}
- 定义切点:在切面类中,使用
@Pointcut
注解定义切点,即指定在哪些方法或类上应用切面逻辑。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class MyAspect {@Pointcut("execution(* com.example.MyClass.myMethod(..))")public void myPointcut() {}
}
- 定义通知:在切面类中,定义各种通知类型的方法,如前置通知、后置通知、环绕通知等。使用
@Before
、@After
、@Around
等注解来标识通知类型。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class MyAspect {@Before("myPointcut()")public void beforeAdvice() {// 在切点方法执行前执行的逻辑}
}
- 配置织入:根据使用的方式(静态织入或动态织入),配置编译器或运行时织入器来将切面逻辑织入到目标代码中。
-
静态织入:使用AspectJ编译器,在编译期间将切面织入到目标代码中。可以使用AspectJ编译器命令行工具或IDE插件来进行编译。
-
动态织入:在运行时使用AspectJ织入器,通过Java命令行参数或配置文件指定织入器。
以上是使用AspectJ进行切面编程的基本步骤。根据具体的需求和场景,可以进一步扩展和配置切面逻辑,使用AspectJ提供的更多特性和语法。
2. Spring AOP
Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种轻量级的AOP框架。它通过在运行时动态地将切面逻辑织入到应用程序中,实现了横切关注点的处理。
以下是Spring AOP的一些主要特点和功能:
-
基于代理的AOP:Spring AOP使用代理模式来实现AOP。它通过创建目标对象的代理对象,并将切面逻辑织入到代理对象中,从而实现对目标对象方法的增强。
-
切点和通知:Spring AOP支持使用切点(Pointcut)来定义需要应用切面逻辑的连接点,例如方法调用或字段访问等。它提供了多种类型的通知(Advice),包括前置通知(@Before)、后置通知(@After)、返回通知(@AfterReturning)、异常通知(@AfterThrowing)和环绕通知(@Around),以实现在切点处执行的切面逻辑。
-
自动代理:Spring AOP支持自动代理,可以根据配置自动创建代理对象,并将切面逻辑织入到目标对象中。通过使用
@EnableAspectJAutoProxy
注解或配置文件中的<aop:aspectj-autoproxy>
元素,可以启用自动代理功能。 -
切面的模块化:Spring AOP支持将切面逻辑模块化,可以将切面逻辑定义为一个独立的切面类,以实现切面逻辑的重用和解耦。
-
与Spring框架集成:Spring AOP与Spring框架无缝集成,可以与其他Spring特性(如依赖注入)一起使用,提供更强大的功能和灵活性。
-
不支持跨类的切面织入:Spring AOP基于代理模式实现,只能对方法级别的连接点进行切面织入,不支持跨类的切面织入。
总的来说,Spring AOP是一个简单而强大的AOP框架,可以帮助开发人员实现横切关注点的处理。它提供了基于代理的AOP机制、切点和通知的灵活组合、自动代理的支持以及与Spring框架的无缝集成。通过使用Spring AOP,开发人员可以更轻松地实现日志记录、事务管理、性能监控等横切关注点的功能。
2.1 使用Spring AOP进行切面编程
下面是一个使用注解的示例,演示如何使用Spring AOP来记录方法执行时间:
-
引入依赖:确保项目中包含Spring AOP的相关依赖。
-
定义切面:创建一个切面类,并使用
@Aspect
注解进行标记。
@Aspect
@Component
public class LoggingAspect {// 定义切点,匹配所有的public方法@Pointcut("execution(public * com.example.MyService.*(..))")public void publicMethods() {}// 编写通知,在方法执行前和执行后记录执行时间@Around("publicMethods()")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();long executionTime = endTime - startTime;System.out.println(joinPoint.getSignature() + " 执行时间:" + executionTime + "ms");return result;}
}
- 配置AOP:使用
@EnableAspectJAutoProxy
注解启用自动代理。
@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);// ...MyService myService = context.getBean(MyService.class);myService.doSomething();// ...}
}
在上述示例中,我们创建了一个切面类LoggingAspect
,并在其中定义了一个切点publicMethods()
,它匹配com.example.MyService
类中的所有public方法。然后,我们使用@Around
注解编写了一个通知,用于在方法执行前和执行后记录执行时间。
通过在应用程序的主类上添加@EnableAspectJAutoProxy
注解,我们启用了自动代理,使得Spring能够自动创建代理对象并织入切面逻辑。
当运行应用程序时,每次调用MyService
类中的方法时,切面逻辑将记录方法的执行时间,并输出到控制台。
这个示例演示了如何使用注解来定义切面和通知,以及如何配置和启用自动代理。通过使用注解,我们可以更简洁地定义切面逻辑,并将其与特定方法或类关联起来。
2.2 如何决定使用哪种动态代理
在Spring AOP中,默认情况下,自动代理使用基于Java动态代理(Java Dynamic Proxy)实现。
Java动态代理是Java语言提供的一种代理机制,通过在运行时动态生成代理类和代理对象来实现代理功能。它基于接口(Interface)来创建代理对象,对目标对象的方法进行代理,并在代理对象的方法中调用目标对象的方法。
Java动态代理有一个限制,即只能代理实现了接口的类。因此,如果目标对象没有实现接口,Spring AOP将无法使用Java动态代理进行自动代理。
当目标对象实现了接口时,Spring AOP将使用Java动态代理来创建代理对象,并将切面逻辑织入到代理对象中。
如果目标对象没有实现接口,Spring AOP将尝试使用CGLib(Code Generation Library)来创建代理对象。CGLib是一个强大的代码生成库,它通过继承目标类来创建代理对象,并使用字节码增强技术来实现代理功能。
总之,当目标对象实现了接口时,Spring AOP默认使用Java动态代理来创建代理对象。当目标对象没有实现接口时,Spring AOP将使用CGLib来创建代理对象。可以通过配置来指定使用哪种代理方式。
2.3 如何通过配置指定代理方式
在Spring中,可以通过配置来指定使用哪种代理方式(Java动态代理或CGLib)。以下是两种常用的配置方式:
- 通过
<aop:aspectj-autoproxy>
元素配置:
<aop:aspectj-autoproxy proxy-target-class="true"/>
在Spring的配置文件中,可以使用<aop:aspectj-autoproxy>
元素来启用自动代理,并通过proxy-target-class
属性来指定是否使用CGLib代理。将proxy-target-class
属性设置为true
表示使用CGLib代理,设置为false
或省略该属性表示使用Java动态代理。
- 通过
@EnableAspectJAutoProxy
注解配置:
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {// 配置其他Bean和AOP切面
}
在Spring的Java配置类中,可以使用@EnableAspectJAutoProxy
注解来启用自动代理,并通过proxyTargetClass
属性来指定是否使用CGLib代理。将proxyTargetClass
属性设置为true
表示使用CGLib代理,设置为false
表示使用Java动态代理。
通过以上配置方式,可以灵活地指定使用哪种代理方式。根据具体的需求和场景,选择合适的代理方式来实现AOP功能。
2.4 Spring AOP和AspectJ的关系
Spring AOP与AspectJ之间存在一定的关联。Spring AOP可以与AspectJ进行集成,利用AspectJ的注解或XML配置来定义切面,并通过Spring AOP将切面织入到目标对象中。这样,Spring AOP可以结合AspectJ的强大功能和语法,实现更灵活和强大的AOP编程。
Spring AOP是通过动态代理实现AOP的,它并不直接借助AspectJ的编译器和织入工具。虽然Spring AOP的实现受到了AspectJ的影响,并且与AspectJ有很好的集成,但Spring AOP并不使用AspectJ的编译器来修改字节码或进行静态织入。
在Spring AOP中,切面逻辑是通过动态代理来织入到目标对象中的。Spring AOP使用JDK动态代理或CGLIB动态代理来创建代理对象,并在代理对象的方法调用前后织入切面逻辑。这种动态织入的方式使得Spring AOP更加灵活和轻量级,但相对于AspectJ而言,它在切面编程的能力上可能略有限制。
3. Spring Boot AOP
Spring 中的 AOP,有接口就用 JDK 动态代理,没有接口就用 Cglib 动态代理。
Spring Boot 中的 AOP,2.0 之前和 Spring 一样;2.0 之后首选 Cglib 动态代理,如果用户想要使用 JDK 动态代理,需要自己手动配置。
4. 扩展
4.1 AspectJ织入方式详解
AspectJ提供了两种方式来配置织入方式:静态织入和动态织入。
- 静态织入:静态织入是在编译期间将切面逻辑织入到目标代码中。要配置静态织入,可以使用AspectJ编译器命令行工具或IDE插件。
-
使用AspectJ编译器命令行工具:可以使用
ajc
命令来编译包含AspectJ切面的代码。在命令行中指定目标代码和切面代码的路径,AspectJ编译器会将切面逻辑织入到目标代码中生成织入后的字节码文件。 -
使用IDE插件:常见的Java开发工具(如Eclipse、IntelliJ IDEA)提供了AspectJ插件,可以在IDE中配置AspectJ切面,并通过插件进行编译和织入。可以通过插件的配置界面或注解来指定切面逻辑的织入方式。
- 动态织入:动态织入是在运行时通过AspectJ织入器来动态地将切面逻辑织入到目标代码中。要配置动态织入,可以通过Java命令行参数或配置文件指定织入器。
-
Java命令行参数:在运行Java程序时,可以使用
-javaagent
参数指定AspectJ织入器,织入器会在程序启动时加载并根据配置文件将切面逻辑织入到目标代码中。 -
配置文件:可以创建一个AspectJ配置文件(通常是XML格式),在配置文件中指定要织入的切面和切点,以及织入方式。然后,在运行Java程序时指定该配置文件,AspectJ织入器会根据配置文件将切面逻辑织入到目标代码中。
无论是静态织入还是动态织入,配置织入方式都需要指定切面的位置和目标代码的位置,并选择合适的织入时机。具体的配置方式和细节可以根据使用的工具和需求而有所不同。
通过上述介绍,希望大家能够明白AspectJ和Spring AOP框架的原理及实现方式,以及了解Spring AOP采用了AspectJ的注解但没有采用其织入方式,而是通过动态代理的方式(JDK动态代理和CGLIB动态代理)生成代理类和代理对象。Spring AOP支持自动代理,如果目标对象实现了接口,则会采用JDK动态代理,如果没有实现接口则采用CGLIB动态代理。可以通过配置改变使用哪种动态代理,Spring Boot2.0前后的默认配置不同等。
参考
JDK动态代理和CGLib动态代理的对比
Spring Boot 中的 AOP,到底是 JDK 动态代理还是 Cglib 动态代理?
相关文章:

Java AOP Framework概述
Java AOP Framework概述 1. AspectJ1.1 使用AspectJ进行切面编程 2. Spring AOP2.1 使用Spring AOP进行切面编程2.2 如何决定使用哪种动态代理2.3 如何通过配置指定代理方式2.4 Spring AOP和AspectJ的关系 3. Spring Boot AOP4. 扩展4.1 AspectJ织入方式详解 参考 Java常用的AO…...

220V转12V芯片-交流45v-265v输入,固定12v输出峰值电流600MA
标题:220V转12V芯片,实现宽电压输入和固定12V输出 摘要:本文介绍了一款具备宽电压输入范围(45V-265V)和固定12V输出的220V转12V芯片。该芯片内置了650V高压MOS管,并通过CS电阻调节输出电流,最大…...

TOGAF架构开发方法—初步阶段
本章描述了满足新企业体系结构业务指令所需的准备和启动活动,包括组织特定体系结构框架的定义和原则的定义。 一、目标 初步阶段的目标是: 确定组织所需的体系结构功能: 审查进行企业架构的组织背景确定受体系结构功能影响的企业组织的元素并确定其范围确定与架构功能相交的…...

软件定制APP开发步骤分析|小程序
软件定制APP开发步骤分析|小程序 软件定制开发步骤: 1.需求分析: 这是软件定制开发的第一步,也是最关键的一步。在这个阶段,软件开发团队需要与客户进行沟通,了解客户的具体需求和期望。通过讨论和交流,确…...

postman接口传参案例
目录 案例1: 接口A 接口B 案例2: //断言 案例1: 接口A 根据返回值需要从返回值中提取userid值,在Tests标签栏下编写脚本 //获取返回的响应值,并转化为json格式 var jsonData pm.response.json(); // 获取返回…...

【2023华为杯A题】WLAN网络信道接入机制建模(代码、思路.....)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

CFCA企业版通配符SSL证书
CFCA是中国CFCA企业版通配符SSL证书金融认证中心的缩写,即China Financial Certification Authority。它是一家经过中国人民银行和国家信息安全机构批准成立的国家级权威安全认证机构,也是国际CA浏览器联盟组织(CA/Browser Forum)…...

基于ASCON的AEAD
1. 引言 前序博客: ASCON:以“慢而稳”赢得NIST轻量级加密算法标准密码学中的AEAD(authenticated encryption with associated data) 对称密钥加密过去数年来已发生改变,具体为: 当今主要使用stream ciphers,因其比…...
汇编宏伪指令介绍
1、汇编宏伪指令介绍 .macro macname macargs .endm(1)“.macro"和”.endm"表示宏定义的开始和结束; (2) “.macro"后面接着宏定义的名字,然后是参数,参数后面的宏定义的实现…...

优化系统报错提示信息,提高人机交互(一)
1、常规报错及处理 package com.example.demo.controller;import com.example.demo.service.IDemoService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.w…...

FPGA纯verilog实现8路视频拼接显示,提供工程源码和技术支持
目录 1、前言版本更新说明免责声明 2、我已有的FPGA视频拼接叠加融合方案3、设计思路框架视频源选择OV5640摄像头配置及采集静态彩条视频拼接算法图像缓存视频输出 4、vivado工程详解5、工程移植说明vivado版本不一致处理FPGA型号不一致处理其他注意事项 6、上板调试验证并演示…...

spring boot项目一次性能测试的总结
满足标准:并发大于等于100 ,平均响应时间小于等于3秒 项目在压测过程中并发数只有50,在并发数100的情况下有很多请求链接是失败的 我们该如何入手去处理这些问题并提高并发数呢? 1、首先从压测结果入手,对不满足标准…...

10分钟设置免费海外远程桌面
前言 本教程将向您介绍如何使用 Amazon Lightsail 服务的免费套餐轻松搭建属于您的远程桌面。依托于 Amazon 全球可用区,您可以在世界各地搭建符合您配置需求的远程桌面。 本教程需要先拥有亚马逊云科技海外账户。现在注册亚马逊云科技账户可以享受12个月免费套餐…...

基于复旦微的FMQL45T900全国产化ARM核心模块(100%国产化)
TES745D是一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板。该核心板将复旦微的FMQL45T900(与XILINX的XC7Z045-2FFG900I兼容)的最小系统集成在了一个87*117mm的核心板上,可以作为一个核心模块,进行功能性扩展,能…...

2023.9.11 关于传输层协议 UDP和TCP 详解
目录 UDP协议 TCP协议 TCP十大核心机制 确认应答 超时重传 连接管理(三次握手 四次挥手) 滑动窗口 流量控制 拥塞控制 延时应答 捎带应答 面向字节流 粘包问题 TCP 中的异常处理 经典面试题 对比 TCP 和 UDP 如何使用 UDP 实现可靠传…...

thinkphp8路由
thinkphp8已出来有好一段时间了。这些天闲来无事,研究了下tp8的路由。默认情况下,tp8的路由是在route\app.php的文件里。但在实际工作中,我们并不会这样子去写路由。因为这样不好管理。更多的,是通过应用级别去管理路由。假如项目…...

Python统计pdf中英文单词的个数
之前的文章提供了批量识别pdf中英文的方法,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文上。以及自动pdf英文转中文文档,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文下。 本文实现python统计pdf中英文字符的个数。 文章目录 一、要统计字符的pdf…...

Kindle电子书下载功能关闭怎么办,借助calibre和cpolar搭建私有的网络书库公网访问
Kindle中国电子书店停运不要慌,十分钟搭建自己的在线书库随时随地看小说! 文章目录 Kindle中国电子书店停运不要慌,十分钟搭建自己的在线书库随时随地看小说!1.网络书库软件下载安装2.网络书库服务器设置3.内网穿透工具设置4.公网…...

ubuntu、linux in window安装docker教程
1、首先进入管理员权限。 2、更新软件源。 sudo apt update 3、安装一些依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common 4、为系统添加Docker的密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-k…...

clickhouse学习之路----clickhouse的特点及安装
clickhouse学习笔记 反正都有学不完的技术,不如就学一学clickhouse吧 文章目录 clickhouse学习笔记clickhouse的特点1.列式存储2. DBMS 的功能3.多样化引擎4.高吞吐写入能力5.数据分区与线程级并行 clickhouse安装1.关闭防火墙2.CentOS 取消打开文件数限制3.安装依…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...