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

使用After增强处理

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

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

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

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

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

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

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

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

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

使用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增强处理:

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

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

在AdviceManager类中增加以下内容:

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

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

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

    执行测试类,结果如下:

    

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

    《Spring中的AOP系列三、四、五》的代码在这里:点击下载,欢迎留言提意见。

    【未完,待续】

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Spring的AOP的注解的通知类型,切入点的注解

Spring的注解的AOP的通知类型@Before:前置通知@AfterReturning:后置通知@Around:环绕通知@AfterThrowing:异常抛出通知@After:最终通知@Pointcut:切入点的注解1/

Spring中的AOP(七)——基于XML配置文件方式的AOP

  除了前面介绍的基于JDK1.5的注解方式来定义切面,切入点和增强处理外,SpringAOP也允许直接使用XML配置文件来管理它们。在JDK1.5之前,只能使用配置文件的方式来管理,在Spring2.X后提供了一个新的aop命名空间来定义切面、切入点和增强处理。相比之下,使用XML配置文件方式有如下优点:如果没有使用JDK1.5以上