文章目录
before(前置通知)
特点
会在连接点之前执行
运用场景
权限控制,方法的调用日志,执行目标方法的前置方法(例如支付环境安全监测)
xml编辑语法
<!--
配置切面
ref:配置的切面的id
-->
<aop:aspect ref="safe">
<!--
前置通知
method:配置的切面的一个方法的方法名
pointcut-ref:连接点的id
-->
<aop:before method="monitorSafe" pointcut-ref="pt" />
</aop:aspect>
after-returning(后置通知)
特点
会在连接点执行后执行
运用场景
执行目标方法的后置方法(例如取钱后发送短信通知)
xml编辑语法
<!--
配置切面
ref:配置的切面的id
-->
<aop:aspect ref="safe">
<!--
带返回值的后置通知
method:配置的切面的一个方法的方法名
pointcut-ref:连接点的id
returning:通知的形参参数名
-->
<aop:after-returning method="print_getMoney_log" returning="money" pointcut-ref="pt" />
</aop:aspect>
坑
当我们的连接点范围比较广时,会有这样一种情况
有两个函数都有返回值,而且返回值的名字都叫demo,但是一个是String类型一个是int类型,
这个时候如果我们把after-returning通知的形参的类型定义为String或者别的什么类型,那到时候肯定会发生错误,
所以在使用after-returning通知时,形参的类型最好定义成Object
after-throwing(异常通知)
特点
会在出现异常的时候调用
运用场景
异常处理(引导用户进入一个较友好的页面,而不是500或者404),记录异常日志,通知管理员等
xml编辑语法
<!--
配置切面
ref:配置的切面的id
-->
<aop:aspect ref="exception">
<!--
发生异常时会执行的通知
method:配置的切面的一个方法的方法名
pointcut-ref:连接点的id
throwing :存入的异常对象的形参名
-->
<aop:after-throwing method="prinException" throwing = "e" pointcut-ref="pt" />
</aop:aspect>
around(环绕通知)
特点
会在连接点之前与之后都会调用
运用场景
日志、缓存、权限、性能监控、事务管理
xml编辑语法
<!--
配置切面
ref:配置的切面的id
-->
<aop:aspect ref="purViewImpl">
<!--
发生异常时会执行的通知
method:配置的切面的一个方法的方法名
pointcut-ref:连接点的id
throwing :存入的异常对象的形参名
-->
<aop:around method="verification" pointcut-ref="pt" />
</aop:aspect>
after(最终通知)
特点
一定会在连接点执行完以后执行,类似于finaly
运用场景
释放资源 (关闭文件、 关闭数据库连接、 网络连接、 释放内存对象 )
xml编辑语法
<!--
配置切面
ref:配置的切面的id
-->
<aop:aspect ref="exception">
<!--
发生异常时会执行的通知
method:配置的切面的一个方法的方法名
pointcut-ref:连接点的id
-->
<aop:after-throwing method="prinException" pointcut-ref="pt" />
</aop:aspect>
总结
在通常的业务逻辑中,这五种通知的执行顺序如下
try
{
//环绕通知proceed前的逻辑
// 执行前置通知;
// 执行目标方法;
环绕通知proceed后的逻辑
// 执行返回通知;
}
catche(Exception e)
{
// 执行异常通知;
}
finally
{
// 执行后置通知;
}