注解AOP
AOP的基本概念
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
基于注解的AOP配置方式
1.启用@AsjectJ支持
在applicationContext.xml中配置下面一句:
<aop:aspectj-autoproxy />
2.通知类型介绍
(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可
(2)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值
(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名
来访问目标方法中所抛出的异常对象
(4)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
代理示例
(1)添加依赖文件
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 | <properties> <java.version> 18 </java.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version> 4.0 . 0 .RELEASE</version> </dependency> <!-- https: //mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version> 4.0 . 0 .RELEASE</version> </dependency> <!-- https: //mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version> 4.0 . 0 .RELEASE</version> </dependency> <!-- https: //mvnrepository.com/artifact/commons-logging/commons-logging --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version> 1.1 . 1 </version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version> 4.12 </version> <scope>compile</scope> </dependency> <!-- https: //mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version> 4.0 . 0 .RELEASE</version> </dependency> <!-- https: //mvnrepository.com/artifact/cglib/cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version> 2.2 . 2 </version> </dependency> <!-- https: //mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version> 1.8 . 13 </version> </dependency> <!-- https: //mvnrepository.com/artifact/aopalliance/aopalliance --> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version> 1.0 </version> </dependency> </dependencies><build><br> <finalName>AOPTest</finalName><br> <plugins><br> <plugin><br> <groupId>org.apache.maven.plugins</groupId><br> <artifactId>maven-compiler-plugin</artifactId><br> <version> 3.8 . 1 </version><br> <configuration><br> <!--根据个人需要自己修改--><br> <source> 8 </source><br> <target> 8 </target><br> </configuration><br> </plugin><br> </plugins><br></build> |
(2)配置文件开启切面注解(applicationContext.xml):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version= "1.0" encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "http://www.springframework.org/schema/context" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:aop= "http://www.springframework.org/schema/aop" xsi:schemaLocation="http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context.xsd http: //www.springframework.org/schema/aop http: //www.springframework.org/schema/aop/spring-aop.xsd http: //www.springframework.org/schema/tx http: //www.springframework.org/schema/tx/spring-tx.xsd"> <context:component-scan base- package = "com.gqx.anno" /> <aop:aspectj-autoproxy /> </beans> |
(3)创建目标类
1 2 3 4 5 6 | @Component (value = "studentService" ) public class StudentService { public void eat(){ System.out.println( "我要开始吃午饭了" ); } } |
(4)切面增强
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 | @Component @Aspect public class AnnoAspect { @Pointcut ( "execution(* com.gqx.anno.StudentService.*(..))" ) public void pointCut(){} @Before ( "execution(* com.gqx.anno.StudentService.*(..))" ) public void doBefore(JoinPoint joinPoint){ System.out.println( "AOP Before Advice..." ); } @After ( "pointCut()" ) public void doAfter(JoinPoint joinPoint){ System.out.println( "AOP After Advice..." ); } @AfterReturning (pointcut= "pointCut()" ,returning= "returnVal" ) public void afterReturn(JoinPoint joinPoint,Object returnVal){ System.out.println( "AOP AfterReturning Advice:" + returnVal); } @AfterThrowing (pointcut= "pointCut()" ,throwing= "error" ) public void afterThrowing(JoinPoint joinPoint,Throwable error){ System.out.println( "AOP AfterThrowing Advice..." + error); System.out.println( "AfterThrowing..." ); } @Around ( "pointCut()" ) public void around(ProceedingJoinPoint pjp){ System.out.println( "AOP Aronud before..." ); try { pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println( "AOP Aronud after..." ); } } |
(5)主运行类
1 2 3 4 5 6 7 8 9 10 | public class AppMain { public static void main(String[] args) { //1. 创建IoC容器对象,加载spring核心配置文件 //初始化Spring容器ApplicationContext,加载配置文件 ApplicationContext application = new ClassPathXmlApplicationContext( "applicationContext.xml" ); //2. 从IOC容器中获取Bean对象 StudentService studentService = (StudentService) application.getBean( "studentService" ); studentService.eat(); } } |
若运行出错:
Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @9d5509a
在idea的vm中添加下面的选项
1 | --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人