重新写个demo练习spring aop编程。

新的心得:

当不确定参数值时,用两个.是可以代替的。

一、创建最基本的spring工程

(1)创建新的java工程

创建lib文件夹,导入spring和spring aop必须的包,add to build path。

(2)创建方法类和接口

(3)配置xml文件

配置自动扫描,等下配置注解引入bean。

(4)将方法类引入ioc容器,使用注解

(5)配置实现类,尝试运行

当然也可以换一种getBean的方式:

运行结果:

正常运行。

二、实现spring aop

(1)创建日志类

(2)加上注解

解释一下:

  1. 切面一定是要在ioc容器里面:@Component。
  2. 要让spring知道这个类是切面:@Aspect。
  3. 要让spring知道什么时候执行这个before方法:@Before。
  4. 要让spring知道在执行什么类里面的什么方法的时候执行这个before方法:”execution(public int test.calculator.*(int, int))”。

(3)配置xml,配置自动为匹配aspectJ注解的java类生成代理对象

试运行:

成功运行前置通知。

(4)这样还不够,我想要实现日志的细节

加入joinpoint对象。

解释一下:

  1. Arrays.asList(joinPoint.getArgs()),getArgs()得到的参数是一个对象数组Object []。
  2. joinPoint.getArgs()实际上等同于Object [] methodargs = joinPoint.getArgs(),然后通过List转成string才得以输出。

为了实现效果更加明显,在main中写多一个方法sub()

执行结果:

(5)这只是前置通知而已,我现在想实现后置通知

运行结果:

三、重头戏,尝试实现返回通知、异常通知、环绕通知

(1)返回通知

返回通知,是代码正常结束后所执行的代码,是可以访问到方法的返回值的。

也就是说,不正常结束是不会触发返回通知的。

解读一下:

  1. value:就是什么类执行什么方法,也就是执行方法的时机。
  2. returning:指定返回值的名称为result,这个返回值一定要和下面的Object result对应,如果不对应会报以下错误:Returning argument name ‘result’ was not bound in advice arguments。
  3. Object result:返回值。

执行结果:

当除数为0时,结果为:

报错除0,返回通知不执行。

(2)异常通知

只有报错的时候才会执行异常通知,正确的时候是不会执行的。

解读一下:

  1. throwing:指定返回值的名称为mistake,这个返回值一定要和下面的Object mistake对应,如果不对应会报以下错误:Returning argument name ‘mistake’ was not bound in advice arguments。
  2. Object mistake:返回的错误。

当被除数为0的时候报错,结果为:

也可以指定异常的输出:

指定了NullPointerException错误,那么只有空指针异常的情况下才会进行异常通知。

可以看到,当前就算/0也没有出现异常通知。

(3)环绕通知

功能是最强的,但是并不常用。

环绕通知需要携带ProceedingJoinPoint类型的参数。

环绕通知类似于动态代理的全过程:

  1. ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
  2. 环绕通知必须有返回值,返回值即为目标方法的返回值。

返回结果为:

返回值全部变成100。

因为return 100,使所有输出值都变成 100。

然而环绕通知十分强大,一个方法就可以完成以上所有方法的工作。

有没有发现,这个环绕方法的实现原理非常类似于动态代理的全过程?

如果对Spring动态代理玩得很转,确实可以使用环绕方法。但是水平要求比较高,所有的方法实际上都需要自己手动实现。

输出结果:

当被除数为0时,报错:

环绕方法非常不常用,只需要了解就可以了。

四、总结

记录一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注