AOP的五种通知类型
- 前置通知:@Before注解
- 后置通知:@After注解
- 环绕通知:@Around注解(掌握)
- 返回后通知:@AfterReturning(了解)
- 异常后通知:@AfterThrowing(了解)
- 通知类型总结
前置通知:@Before注解
在method方法上添加@Before注解
@Component
@Aspect
public class MyAdvice {
/**
* 定义切入点
*/
@Pointcut("execution(int com.itheima.dao.BookDao.update())")
public void pt(){}
/**
* 定义一个共性方法
* 切面 绑定通知 和 切入点
*/
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
后置通知:@After注解
在method方法上添加@After注解
@Component
@Aspect
public class MyAdvice {
/**
* 定义切入点
*/
@Pointcut("execution(int com.itheima.dao.BookDao.update())")
public void pt(){}
/**
* 定义一个共性方法
* 切面 绑定通知 和 切入点
*/
@After("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
环绕通知:@Around注解(掌握)
在方法上方加上@Around注解;
@Component
@Aspect
public class MyAdvice {
/**
* 定义切入点
*/
@Pointcut("execution(int com.itheima.dao.BookDao.update())")
public void pt(){}
/**
* 定义一个共性方法
* 切面 绑定通知 和 切入点
* 执行环绕通知的时候ProceedingJoinPoint pjp参数一定要有,只有通过该参数调用pip.proceed方法才能执行原始方法的内容。
* pip.proceed()调用原始方法会有一个Object res类型的返回值,如果原始方法有返回值则res对该返回值进行接收并且可以进行返回,如果没有返回值则res=null.
*/
@Around("pt()")
public Object method(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("before around ....");
// 表示对原始操作的调用
Object res = pjp.proceed();
System.out.println("原始方法中的返回值为:" + res);
System.out.println("after around ....");
return res;
}
}
环绕通知注意事项
- 环绕通知必须依赖形参 ProceedingJoinPoint 才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知。
- 通知中如果未使用 ProceedingJoinPoint 对原始方法进行调用将跳过原始方法的执行。
- 对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,最好设定为Object类型。
- 原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void,也可以设置成Object。
- 由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须要处理Throwable异常。
返回后通知:@AfterReturning(了解)
在方法上方加上@AfterReturning注解;
@Component
@Aspect
public class MyAdvice {
/**
* 定义切入点
*/
@Pointcut("execution(int com.itheima.dao.BookDao.update())")
public void pt(){}
/**
* 定义一个共性方法
* 切面 绑定通知 和 切入点
*/
@AfterReturning("pt()")
public void method() throws Throwable {
System.out.println("AfterReturning .... ");
}
}
异常后通知:@AfterThrowing(了解)
在方法上方加上@AfterThrowing注解;
@Component
@Aspect
public class MyAdvice {
/**
* 定义切入点
*/
@Pointcut("execution(int com.itheima.dao.BookDao.update())")
public void pt(){}
/**
* 定义一个共性方法
* 切面 绑定通知 和 切入点
*/
@AfterThrowing("pt()")
public void method() throws Throwable {
System.out.println("AfterThrowing .... ");
}
}
通知类型总结
知识点1:@Before
名称 | @Before |
---|---|
类型 | 方法注解 |
位置 | 通知方法定义上方 |
作用 | 设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前运行 |
知识点2:@After
名称 | @After |
---|---|
类型 | 方法注解 |
位置 | 通知方法定义上方 |
作用 | 设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法后运行 |
知识点3:@Around
名称 | @Around |
---|---|
类型 | 方法注解 |
位置 | 通知方法定义上方 |
作用 | 设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前后运行 |
知识点4:@AfterReturning
名称 | @AfterReturning |
---|---|
类型 | 方法注解 |
位置 | 通知方法定义上方 |
作用 | 设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法正常执行完毕后执行 |
知识点5:@AfterThrowing
名称 | @AfterThrowing |
---|---|
类型 | 方法注解 |
位置 | 通知方法定义上方 |
作用 | 设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法运行抛出异常后执行 |