参考:https://www.jianshu.com/p/2487cb852f0b
参考:https://blog.csdn.net/qq_37933685/article/details/81673831
说明
前置通知[Before advice]:
在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。
正常返回通知[After returning advice]:
在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
异常返回通知[After throwing advice]:
在连接点抛出异常后执行。
返回通知[After (finally) advice]:
在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
环绕通知[Around advice]:
环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
执行顺序
具体代码顺序
/**
* author: Veng Su
* email: suveng@163.com
* date: 2018/8/14 16:22
*/
@Component(value = "annotationAspect")
@Aspect
public class AnnotationAspect {
//before 切
@Before(value = "execution(* *..*.*.say())")
public void beforeF(){
System.out.println("我是before");
}
//after 切
@After(value = "execution(* *..*.*.say())")
public void afterF(){
System.out.println("我是after");
}
//after_throwing 切
@AfterThrowing(value = "execution(* *..*.*.say())")
public void afterTF(){
System.out.println("我是after-throwing");
}
//after-returning 切
@AfterReturning(value = "execution(* *..*.*.say())")
public void afterRF(){
System.out.println("我是after-returning");
}
//around 切 要把joinpoint给传进来
@Around(value = "AnnotationAspect.say()")
public void aroundF(ProceedingJoinPoint joinPoint){
System.out.println("前around");
try {
joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("后 around");
}
// 如果切入表达式,大部分都是一样的话,则可考虑抽取出来,简单利用
@Pointcut(value = "execution(* *..*.*.say())")
public void say() {}
}
测试代码: 部分非关键代码被省略
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/config/beans.xml")
public class SpringTest {
@Resource(name = "userDao")
UserDao userDao;
@Test
public void testAnnotationAop(){
userDao.say();
}
}