博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AspectJ 通知类型及其实现
阅读量:3905 次
发布时间:2019-05-23

本文共 5828 字,大约阅读时间需要 19 分钟。

文章目录

AspectJ 是什么

AspectJ 是一个基于Java语言的AOP框架

Spring2.0 以后新增了对AspectJ切面表达式的支持

@AspectJ 是Aspect1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面。新版本Spring框架,建议使用AspectJ方式来开发AOP

AspectJ 通知类型

before : 前置通知(应用:各种校验)

​ 在方法执行前执行,如果通知抛出异常,阻止方法运行。

afterReturning:后置通知(应用: 常规数据处理)

​ 方法正常返回后执行,如果方法中抛出异常,通知无法执行。

around:环绕通知(应用:十分强大,可以做任何事)

​ 方法执行前后分别执行,可以阻止方法的执行

​ 必须手动执行方法

afterThrowing: 抛出异常通知(应用:包装异常信息)

​ 方法抛出异常后执行,如果方法没有抛出异常,无法执行

after:最终通知(应用:清理现场)

​ 方法执行完毕后执行,无论方法中是否出现异常

Aspect 实现通知

基于XML实现

  1. 目标类
public class UserServiceImpl implements UserService {
@Override public String addUser() {
//这里用于测试抛出异常 //int i =1/0; System.out.println("addUser!!! AspectAOPXML"); return "Pig"; } @Override public void deleteUser() {
System.out.println("deleteUser!!! AspectAOPXML"); } @Override public void updateUser() {
System.out.println("updateUser!!! AspectAOPXML"); }}
  1. 切面类
//具体测试会添加相应方法public class MyAspect {
}
  1. 配置xml文件
xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
  1. 为目标类中的目标方法添加通知
    主要是通过配置xml来实现的
    然后需要添加以下内容:

< aop:aspect> 将切面类声明成切面,从而获得通知(方法) ref 切面类的引用

< aop:pointcut > 声明一个切入点,所有的通知都可以使用
expression : 切入点表达式
id : 名称,用于其他通知引用

前置通知

格式:
method: 通知,方法名pointcut:切入点表达式,此表达式只能在当前通知使用pointcut-ref: 切入点引用,可以与其他通知共享切入点通知方法格式: public void myBefore(JoinPoint joinPoint)参数:org.aspectj.lang.JoinPoint 用于描述连接点(目标方法),可以获取目标方法名等信息示例:

切面类的通知方法

public void myBefore(JoinPoint joinPoint){
System.out.println(" before advise "+joinPoint.getSignature().getName());}

xml 中的配置

后置通知

目标方法后执行,获得目标方法的返回值格式:
returning: 通知方法第二个参数的名称通知方法格式: public void myAfterReturning(JoinPoint joinPoint,Object ret)参数1: 连接点描述参数2:类型Object,参数名returning="ret"配置的

示例:

切面类的通知方法

public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("after returning,return:"+ret);}

xml 中的配置

环绕通知

格式:
通知方法格式:public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable 返回值类型:Object 参数类型:ProceedingJoinPoint 抛出异常 执行目标方法:需要执行Object object = proceedingJoinPoint.proceed();

示例:

切面类的通知方法

public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("before"); // 手动执行目标方法 Object object = proceedingJoinPoint.proceed(); System.out.println("after"); return object; }

xml中的配置

抛出异常

throwing :通知方法的第二个参数 通知方法格式: public void myAfterThrowing(JoinPoint joinPoint,Throwable e) 参数1:连接点对象 参数2:获取异常信息,类型Throwable,类型名与throwing="e"的赋值相同

示例:

切面类的通知方法

public  void myAfterThrowing(JoinPoint joinPoint,Throwable e){
System.out.println("Throwing"+ e.getMessage());}

xml中的配置

最终通知

切面类的通知方法

public void myAfter(JoinPoint joinPoint){
System.out.println("After Advice");}

xml中的配置

完整代码

切面类:

public class MyAspect {
public void myBefore(JoinPoint joinPoint) {
System.out.println(" before advise "+joinPoint.getSignature().getName()); } public void myAfterReturning(JoinPoint joinPoint,Object ret) {
System.out.println("after returning,return:"+ret); } public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("before"); // 手动执行目标方法 Object object = proceedingJoinPoint.proceed(); System.out.println("after"); return object; } public void myAfterThrowing(JoinPoint joinPoint,Throwable e) {
System.out.println("Throwing"+ e.getMessage()); } public void myAfter(JoinPoint joinPoint) {
System.out.println("After Advice"); }}

xml配置文件:

-->

基于注解实现

由于只是将在xml中配置的通知用注解代替,所以这里就不一一列举了。

代码展示
目标类:

@Service("userServiceImplId")public class UserServiceImpl implements UserService {
@Override public String addUser() {
// int i =1/0; System.out.println("addUser!!! AspectAOPAnnoation"); return "Pig"; } @Override public void deleteUser() {
System.out.println("deleteUser!!! AspectAOPAnnoation"); } @Override public void updateUser() {
System.out.println("updateUser!!! AspectAOPAnnoation"); }}

切面类:

@Component@Aspectpublic class MyAspect {
//前置通知 @Before("execution(* com.zamao.AspectAOPAnnoation.UserServiceImpl.*(..))") public void myBefore(JoinPoint joinPoint) {
System.out.println(" before advise "+joinPoint.getSignature().getName()); } //配置切入点 @Pointcut("execution(* com.zamao.AspectAOPAnnoation.UserServiceImpl.*(..))") public void setPointCut(){
} //后置通知 @AfterReturning(value = "setPointCut()",returning = "ret") public void myAfterReturning(JoinPoint joinPoint,Object ret) {
System.out.println("after returning,return:"+ret); } //环绕通知 @Around(value = "setPointCut()") public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("before"); // 手动执行目标方法 Object object = proceedingJoinPoint.proceed(); System.out.println("after"); return object; } //抛出异常 @AfterThrowing(value="execution(* com.zamao.AspectAOPAnnoation.UserServiceImpl.*(..))",throwing = "e") public void myAfterThrowing(JoinPoint joinPoint,Throwable e) {
System.out.println("Throwing"+ e.getMessage()); } //最终通知 @After("setPointCut()") public void myAfter(JoinPoint joinPoint) {
System.out.println("After Advice"); }}

xml文件中的配置

转载地址:http://xdaen.baihongyu.com/

你可能感兴趣的文章
POJ 1661 Help Jimmy
查看>>
百练OJ 2755 神奇的口袋(递归+递推)
查看>>
HDU 1003 Max Sum
查看>>
Code Vs 1014 装箱
查看>>
循环队列,队链的实现
查看>>
HDU 2602 Bone Collector (01背包)
查看>>
POJ 1837 Blance (01背包)
查看>>
HDU 2456 饭卡 (01背包)
查看>>
HDU 1559 最大子矩阵
查看>>
Open Judge 4010 :2011
查看>>
百练OJ-2815 城堡问题【DFS】
查看>>
CODE[VS] 1025 选菜 【背包】
查看>>
POJ 1724 ROADS【DFS+剪枝】
查看>>
AOJ 847 整数拆段
查看>>
AOJ 848 分数拆分
查看>>
UVA 133 The Dole Queue 【约瑟夫环】
查看>>
XDOJ 1208 B.笑爷买房 【DFS】
查看>>
部门年度工作总结的内容
查看>>
pandas学习笔记
查看>>
Numpy笔记
查看>>