Spring中的AOP(四)——基于Annotation的配置方式(二)

简介:

使用After增强处理

    Spring还提供了一个After增强处理,它与AfterReturning优点类似,但也有区别:

  • AfterReturning增强处理只有在目标方法正确完成后才会被织入

  • After增强处理不管目标方法如何结束(正确还是异常),它都会被织入

    正是因为这个特点,因此After增强处理必须准备处理正常返回和异常返回两种情况,这种增强处理通常用于释放资源。使用@After注解标注一个方法,即可将该方法转换为After增强处理。使用@After注解是需要指定一个value属性,用于指定该增强处理的切入点,既可以是一个已有的切入点,也可以直接定义切入点表达式。

    在com.abc.advice包下面增加AfterAdviceTest,这个类定义了一个After增强处理:

?
1
2
3
4
5
6
7
@Aspect
public  class  AfterAdviceTest {
     @After (value= "execution(* com.abc.servie.impl.*.afterAdvice*(..))" )
     public  void  releaseResource() {
         System.out.println( "模拟释放数据库连接" );
     }
}

     并在AdviceManager类中增加以下内容:

?
1
2
3
4
//将被AfterAdvice的releaseResource方法匹配
public  void  afterAdvice() {
     System.out.println( "方法: afterAdvice" );
}

    上面定义了一个After增强处理,不管切入点的目标方法如何结束,该增强处理都会被织入。下面是测试结果:

214528_qIjg_1434710.jpg


使用Around增强处理

    @Around注解用于标注Around增强处理,它近似等于Before增强处理和AfterReturning增强处理的总和,Around增强处理既可以在执行目标方法前织入增强动作,也可以在目标方法之后织入增强动作。

    与@Before和@AfterReturning不同的是,@Around甚至可以决定目标方法在什么时候执行,如何执行,甚至可以完全阻止目标方法的执行。@Around可以修改目标方法的参数值,也可以修改目标方法的返回值。

    @Around的功能虽然强大,但通常需要在线程安全的环境下使用,因此,如果使用普通的@Before和@AfterReturning就能解决的问题,就没有必要使用@Around了。如果需要目标方法执行之前和执行之后共享某种数据状态,则应该考虑使用@Around;尤其是需要使用增强处理阻止目标方法的执行,或者需要改变目标方法的参数和执行后的返回值时,就只能使用@Around了。

    可以想象,使用@Around时,也需要指定一个value属性,这个属性依然是用于指定切入点。另外,当定义一个Around增强处理时,该方法的第一个形参必须是ProceedingJoinPoint类型(就是说至少包含一个形参),在增强处理方法体内,调用ProceedingJoinPoint的proceed()方法才会执行目标方法——这就是Around增强处理可以完全控制目标方法的执行时机、如何执行的关键,如果增强处理的方法体内没有调用这个proceed()方法,则目标方法不会执行。

    调用proceed()方法时,还可以传入一个Object[]对象,该数组中的值将被传入目标方法作为执行方法的实参。因此我们可以通过这个参数,修改方法的参数值。

    在com.abc.advice包下面增加AroundAdviceTest,这个类定义了一个Around增强处理:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package  com.abc.advice;
 
import  org.aspectj.lang.ProceedingJoinPoint;
import  org.aspectj.lang.annotation.Around;
import  org.aspectj.lang.annotation.Aspect;
 
@Aspect
public  class  AroundAdviceTest {
     @Around (value= "execution(* com.abc.service.*.around*(..))" )
     public  Object process(ProceedingJoinPoint point)  throws  Throwable {
         System.out.println( "模拟执行目标方法前的增强处理:事务开始..." );
         //修改目标方法的参数
         String[] params =  new  String[]{ "param1" };
         //执行目标方法,并保存目标方法执行后的返回值
         Object returnValue = point.proceed(params);
         System.out.println( "模拟执行目标方法后的增强处理:事务结束..." );
         //返回修改后的返回值
         return  "方法实际返回值:"  + returnValue +  ",这是返回值的后缀" ;
     }
}

    上面定义了一个AroundAdviceTest切面,该切面包含了一个Around增强处理:process()方法,该方法中第一行代码用于模拟调用目标方法之前的处理,第二行修改了目标方法的第一个参数,接下来调用目标方法,后面模拟调用目标方法之后的处理和对返回值的修改。正如前面说的,通过这个process方法,我们可以增加类似于@Before和@AfterReturning的增强处理,可以决定什么时候执行目标方法,可以修改目标方法的参数值,还可以修改目标方法的返回值,真是想做什么就做什么啊!

    在AdviceManager类中增加以下内容:

?
1
2
3
4
5
//将被AroundAdvice的process方法匹配
public  String aroundAdvice(String param1) {
     System.out.println( "方法: aroundAdvice" );
     return  param1;
}

    在com.abc.main.AOPTest中加入方法的调用,触发切点:

?
1
2
String result = manager.aroundAdvice( "param1" );
System.out.println( "返回值:"  + result);

    执行测试类,结果如下:

    225422_exfg_1434710.jpg

    需要注意的是,当调用ProceedingJoinPoint的proceed()方法时,传入的Object[]参数值将作为目标方法的参数,如果这个数组长度与目标方法的参数个数不等,或者数组元素的类型和目标方法的参数类型不匹配,程序就会出现异常。

目录
相关文章
|
7天前
|
SQL Java 数据库连接
(自用)Spring常用配置
(自用)Spring常用配置
14 0
|
1月前
|
监控 Java 开发者
Spring AOP动态代理
Spring AOP动态代理
40 1
|
1月前
|
Java Spring 容器
Spring的AOP失效场景详解
Spring的AOP失效场景详解
88 0
|
23天前
|
设计模式 Java Maven
Spring Aop 底层责任链思路实现-springaopdi-ceng-ze-ren-lian-si-lu-shi-xian
Spring Aop 底层责任链思路实现-springaopdi-ceng-ze-ren-lian-si-lu-shi-xian
31 1
|
29天前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
35 1
|
2月前
|
XML Java 数据格式
5个点轻松搞定Spring AOP底层实现原理
AOP 也是 Spring 中一个较为重要的内容,相对于传统的 OOP 模式,AOP 有很多让人难以理解的地方,本篇文章将向大家介绍 AOP 的实现方法及其底层实现,内容包括:
44 1
|
1天前
|
安全 Java Spring
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
13 0
|
1天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
4 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
|
7天前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
14 1
|
7天前
|
Java 数据库连接 Spring
简化配置,提高灵活性:Spring中的参数化配置技巧
简化配置,提高灵活性:Spring中的参数化配置技巧
17 0