AOP配置(XML)

AspectJ

  • AspectJ(切面)用于描述切入点与通知间的关系,是AOP编程中的一个概念
  • AspectJ是基于java语言对Aspect的实现

AOP配置

  • 名称:aop:config
  • 类型:标签
  • 归属:beans标签
  • 作用:设置AOP
  • 格式:
<beans>
	<aop:config>....</aop:config>
	<aop:config>....</aop:config>
</beans>
  • 说明:
    • 一个beans标签中可以配置多个aop:config标签
  • 基本属性:
    • ref:通知所在的bean的id

AOP配置

  • 名称:aop:pointcut
  • 类型:标签
  • 归属:aop:config标签、aop:aspect标签
  • 作用:设置切入点
  • 格式
<aop:config>
	<aop:pointcut id="pointcutId" expression="..."/>
	<aop:aspect>
		<aop:pointcut id="pointcutId" expression="..."/>
	</aop:aspect>
</aop:config>
  • 说明:
    • 一个aop:config标签中可以配置多个aop:pointcut标签,且该标签可以配置在aop:aspect标签内
  • 基本属性:
    • id:识别切入点的名称
    • expression:切入点表达式

切入点

  • 切入点描述的是某个方法
  • 切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式
  • 关键字(访问修饰符 返回值 包名.类名.方法名 (参数) 异常名)
    • 关键字:描述表达式的匹配模式(参看关键字列表)
    • 访问修饰符:方法的访问控制权限修饰符
    • 类名:方法所在的类(此处可以配置接口名称)
    • 异常:方法定义中指定抛出的异常
  • 范例:
execution(public User com.thenema.aop_xml.service.UserService.findById(int))

切入点表达式—关键字

  • execution:匹配执行指定方法
  • args:匹配带有指定参数类型的方法
  • within:…
  • this:…
  • target:…
  • @within:…
  • @target:…
  • @args:…
  • @annotation:…
  • bean:…
  • reference pointcut:…

切入点表达式—通配符

  • *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现
execution(public * com.thenema.*.UserService.find*(*))
 - 匹配com.thenema包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法
  • …:多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写
execution(public User com..UserService.findById(..))
 - 匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法
  • +:专用于匹配子类类型
execution(* *..*Service+.*(..))

切入点表达式—逻辑运算符

  • &&:连接两个切入点表达式,表示两个切入点表达式同时成立的匹配
  • ||:连接两个切入点表达式,表示两个切入点表达式成立任意一个匹配
  • !:连接单个切入点表达式,表示该切入点表达式不成立的匹配

  • 切入点表达式
    • 关键字
    • 通配符
    • 逻辑运算符

切入点的三种配置方式

<aop:config>
	<!--配置公共切入点-->
	<aop:pointcut id="pt1" expression="execution(* *(..))"/>
	<aop:aspect ref="myAdvice">
		<!--配置局部切入点-->
		<aop:pointcut id="pt2" expression="execution(* *(..))"/>
		<!--引入公共切入点-->
		<aop:before method="logAdvice" pointcut-ref="pt1"/>
		<!--引入局部切入点-->
		<aop:before method="logAdvice" pointcut-ref="pt2"/>
		<!--直接配置切入点-->
		<aop:before method="logAdvice" pointcut="execution(* *(..))"/>
	</aop:aspect>
</aop:config>

切入点配置经验

  • 企业开发命名规范严格遵循规范文档进行
  • 先为方法配置局部切入点
  • 再抽取类中公共切入点
  • 最后抽取全局切入点
  • 代码走查过程中检测切入点是否存在越界性包含
  • 代码走查过程中检测切入点是否存在非包含性进驻
  • 设定AOP执行检测程序,在单元测试中监控通知被执行次数与预计次数是否匹配
  • 设定完毕的切入点如果发生调整务必进行回归测试
    (以上规则适用于XML配置格式)

  • 三种切入点配置方式

通知类型

  • AOP的通知类型共5种
    • 前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行
      • 应用:数据校验
    • 后置通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知
      • 应用:清理现场
    • 返回后通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行
      • 应用:返回值相关数据处理
    • 抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行
      • 应用:对原始方法中出现的异常信息进行处理
    • 环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行
      • 应用:十分强大,可以做任何事情

通知类型:

  • 名称:aop:before
  • 类型:标签
  • 归属:aop:aspect标签
  • 作用:设置前置通知
  • 格式:
<aop:aspect ref="adviceId">
	<aop:before method="methodName" pointcut="..."/>
</aop:aspect>
  • 说明:一个aop:aspect标签中可以配置多个aop:before标签
  • 基本属性:
  • method:在通知类中设置当前通知类别对应的方法
  • pointcut:设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
  • pointcut-ref:设置当前通知对应的切入点id,与pointcut属性冲突

通知类型:

  • 名称:aop:after
  • 类型:标签
  • 归属:aop:aspect标签
  • 作用:设置后置通知
  • 格式:
<aop:aspect ref="adviceId">
	<aop:after method="methodName" pointcut="..."/>
</aop:aspect>
  • 说明:一个aop:aspect标签中可以配置多个aop:after标签
  • 基本属性:
  • method:在通知类中设置当前通知类别对应的方法
  • pointcut:设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
  • pointcut-ref:设置当前通知对应的切入点id,与pointcut属性冲突

通知类型:

  • 名称:aop:after-returning
  • 类型:标签
  • 归属:aop:aspect标签
  • 作用:设置返回后通知
  • 格式:
<aop:aspect ref="adviceId">
	<aop:after-returning method="methodName" pointcut="..."/>
</aop:aspect>
  • 说明:一个aop:aspect标签中可以配置多个aop:after-returning标签
  • 基本属性:
  • method:在通知类中设置当前通知类别对应的方法
  • pointcut:设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
  • pointcut-ref:设置当前通知对应的切入点id,与pointcut属性冲突

通知类型:

  • 名称:aop:after-throwing
  • 类型:标签
  • 归属:aop:aspect标签
  • 作用:设置抛出异常后通知
  • 格式:
<aop:aspect ref="adviceId">
	<aop:after-throwing method="methodName" pointcut="..."/>
</aop:aspect>
  • 说明:一个aop:aspect标签中可以配置多个aop:after-throwing标签
  • 基本属性:
  • method:在通知类中设置当前通知类别对应的方法
  • pointcut:设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
  • pointcut-ref:设置当前通知对应的切入点id,与pointcut属性冲突

通知类型:

  • 名称:aop:after-around
  • 类型:标签
  • 归属:aop:aspect标签
  • 作用:设置环绕通知
  • 格式:
<aop:aspect ref="adviceId">
	<aop:after-around method="methodName" pointcut="..."/>
</aop:aspect>
  • 说明:一个aop:aspect标签中可以配置多个aop:after-around标签
  • 基本属性:
  • method:在通知类中设置当前通知类别对应的方法
  • pointcut:设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
  • pointcut-ref:设置当前通知对应的切入点id,与pointcut属性冲突

环绕通知开发方式

  • 环绕通知是在原始方法的前后添加功能,在环绕通知中,存在对原始方法的显式调用
public Object around(ProceedingJoinPoint pjp) throws Throwable{
	Object ret = pjp.proceed();
	return ret;
}
  • 环绕通知方法相关说明:
    • 方法须设定Object类型的返回值,否则会拦截原始方法的返回。如果原始方法返回值类型为void,通知方法也可以设定返回值类型为void,最终返回null
    • 方法需在第一个参数位置设定ProceedingJoinPoint对象,通过该对象调用proceed()方法,实现对原始方法的调用。如省略该参数,原始方法将无法执行
    • 使用proceed()方法调用原始方法时,因无法预知原始方法运行过程中是否会出现异常,强制抛出Throwable对象,封装原始方法中可能出现的异常信息

通知顺序

  • 当同一个切入点配置了多个通知时,通知会存在运行的先后顺序,该顺序以通知配置的顺序为准

通知获取数据

  • 参数
  • 返回值
  • 异常

通知获取参数数据

  • 设定切入点表达式为通知方法传递参数(锁定通知变量名)
  • 原始方法
public void save(int param1,int param2){
	System.out.println("user service running...");
}
  • AOP配置
<aop:aspect ref="myAdvice">
	<aop:pointcut id="pt" expression="execution(* *(..)) &amp;&amp; args(a,b)"/>
	<aop:before method="before" pointcut-ref="pt"/>
</aop:aspect>
  • 通知类
public void before(int a,int b){
	System.out.printf("a="+a);
	System.out.printf("b="+b);
}

通知中获取返回值


通知获取返回值数据

  • 设定返回值变量名
  • 原始方法
public int save(){
	System.out.println("user service running...");
	return 100;
}
  • AOP配置
<aop:aspect ref="myAdvice">
	<aop:pointcut id="pt3" expression="execution(* *(..))"/>
	<aop:after-returning method="afterReturning" pointcut-ref="pt3" returning="ret"/>
<aop:aspect>
  • 通知类
public void afterReturning(Object ret){
	System.out.println(ret);
}
  • 适用于返回后通知(after-returning)

通知获取返回值数据

  • 在通知类的方法中调用原始方法获取返回值
  • 原始方法
public int save(){
	System.out.println("user service running...");
	return 100;
}
  • AOP配置
<aop:aspect ref="myAdvice">
	<aop:pointcut id="pt3" expression="execution(* *(..))"/>
	<aop:around method="around" pointcut-ref="pt2"/>
<aop:aspect>
  • 通知类
public Object around(ProceedingJoinPoint pjp) throws Throwable{
	Object ret = pjp.proceed();
	return ret;
}
  • 适用于环绕通知(around)

通知中获取异常对象


通知获取异常数据

  • 在通知类的方法中调用原始方法捕获异常
  • 原始方法
public int save(){
	System.out.println("user service running...");
	return 100;
}
  • AOP配置
<aop:aspect ref="myAdvice">
	<aop:pointcut id="pt4" expression="execution(* *(..))"/>
	<aop:around method="around" pointcut-ref="pt4"/>
<aop:aspect>
  • 通知类
public Object around(ProceedingJoinPoint pjp) throws Throwable{
	Object ret = pjp.proceed();  //对此处调用进行try...catch...捕获异常,或抛出异常
	return ret;
}
  • 适用于环绕通知(around)

通知获取异常数据

  • 设置异常对象变量名
  • 原始方法
public int save(){
	System.out.println("user service running...");
	return 100;
}
  • AOP配置
<aop:aspect ref="myAdvice">
	<aop:pointcut id="pt4" expression="execution(* *(..))"/>
	<aop:around method="afterThrowing" pointcut-ref="pt4" throwing="t" />
<aop:aspect>
  • 通知类
public Object around(ProceedingJoinPoint pjp) throws Throwable{
	System.out.println(t.getMessage());
}
  • 适用于返回后通知(after-throwing)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值