配置文件中
</beans>
//切面
@Aspect
public class LogAdvice {
// 声明一个切入点。本方法不能有返回值与参数
@Pointcut("execution(* *(..))")
private void myPointcut() {
}
// 前置通知,在原方法执行之前
@Before("myPointcut()")
public void before() {
System.out.println("== before ==");
}
// 最终通知,在原方法执行之后
// 如果原方法有异常,也会执行
@After("myPointcut()")
public void after() {
System.out.println("== after ==");
}
// 后置通知,在原方法执行之后
// 如果原方法有异常,则不执行。
// 方法一:@AfterReturning("myPointcut()")
// 方法二:@AfterReturning(pointcut = "myPointcut()")
// 可以使用returning参数指定返回值的对应的参数名,Spring就会在调用本方法时把返回值传给指定名称的参数
@AfterReturning(pointcut = "myPointcut()", returning = "returnValue")
public void afterReturning(Object returnValue) {
System.out.println(returnValue);
System.out.println("== afterReturning ==");
}
// 异常通知,在出现异常之后
// @AfterThrowing("myPointcut()")
@AfterThrowing(pointcut = "myPointcut()", throwing = "ex")
public void afterThrowing(Exception ex) {
System.out.println(ex);
System.out.println("== afterThrowing ==");
}
// 环绕通知,在原方法调用的前后执行。
// 在原方法执行出异常后,环绕通知的后面部分不会执行。
// 一定要在执行完原方法后,从本方法中返回结果。
@Around("myPointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("== 环绕通知(前) ==");
Object result = joinPoint.proceed(); // 执行原方法
System.out.println("== 环绕通知(后) ==");
return result;
}
}
@Test
public void testUserService() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
UserService userService = (UserService) ac.getBean("userService");
// ===================================================
// 使用的是代理对象
userService.saveUser();
System.out.println();
userService.queryUsers();
System.out.println();
userService.deleteUser();
System.out.println();
}
通知的执行顺序
前置通知 before
后置通知 afterReturning
异常通知 afterThrowing
最终通知 after
环绕通知(前、后)around
ProceedingJoinPoint
以上所有通知都配置上时,执行结果如下:
1,不抛异常:
== before ==
== 环绕通知(前) ==
>> 删除一个User <<
== after ==
== afterReturning ==
== 环绕通知(后) ==
2,抛异常
== before ==
== 环绕通知(前) ==
>> 查询所有User <<
== after ==
== afterThrows ==