out.println("LoggerAspect-->前置通知,方法名:"+methodName+",参数:"+ Arrays.toString(args));
}
11.3.3.3、在不同一个切面类中复用
// 复用其他切面类中@Pointcut注解定义的切入点表达式,
// @Before注解的value属性值,需要设置为使用了@Pointcut注解标识的(全限定类名+)方法名
@Before("org.rain.spring.aop.annotation.LoggerAspect.pointCutOne()")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect-->前置通知,方法名:"+methodName+",参数:"+ Arrays.toString(args));
}
11.4、其他通知的使用
11.4.1、后置通知
11.4.1.1、配置后置方法
// @After注解:用于将方法标识为后置通知(方法)
@After("pointCutOne()")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect-->后置通知,方法名:"+methodName+",参数:"+ Arrays.toString(args));
}
11.4.1.2、测试使用效果
由控制台日志可知,后置通知在目标对象方法的finally子句中执行(一般用于释放资源)
@Test
public void testAOPByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-aop-annotation.xml");
// 虽然不知道代理对象的类名,但可以通过代理对象和目标对象共同实现的接口类型来从ioc容器中获取代理对象
Calculator calculator = ioc.getBean(Calculator.class);
// 只能通过代理对象来访问目标对象中的方法
calculator.div(1,0);
}
11.4.2、返回通知
11.4.2.1、配置返回通知
/**
* @AfterReturning注解:用于将方法标识为返回通知(方法)
* returning属性:指定(返回)通知方法中的某个参数(名),用于接收目标对象方法的返回值
*/
@AfterReturning(value = "pointCutOne()",returning = "result")
public void afterReturningMethod(JoinPoint joinPoint,Object result){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect-->返回通知,方法名:"+methodName+",结果:"+ result);
}
11.4.2.2、测试使用效果
由控制台日志可知,返回通知在目标对象方法的返回值之后执行
@Test
public void testAOPByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-aop-annotation.xml");
// 虽然不知道代理对象的类名,但可以通过代理对象和目标对象共同实现的接口类型来从ioc容器中获取代理对象
Calculator calculator = ioc.getBean(Calculator.class);
// 只能通过代理对象来访问目标对象中的方法
calculator.div(1,1);
}
11.4.3、异常通知
11.4.3.1、配置异常通知
/**
* @AfterThrowing注解:用于将方法标识为异常通知(方法)
* throwing属性:指定(异常)通知方法中的某个参数(名),用于接收目标对象方法出现的异常
*/
@AfterThrowing(value = "pointCutOne()",throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint,Exception ex){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("LoggerAspect-->异常通知,方法名:"+methodName+",异常:"+ ex);
}
11.4.3.2、测试使用效果
由控制台日志可知,异常通知在目标对象方法的catch子句中执行
@Test
public void testAOPByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-aop-annotation.xml");
// 虽然不知道代理对象的类名,但可以通过代理对象和目标对象共同实现的接口类型来从ioc容器中获取代理对象
Calculator calculator = ioc.getBean(Calculator.class);
// 只能通过代理对象来访问目标对象中的方法
calculator.div(1,0);
}
11.4.4、通知的执行顺序
11.4.4.1、Spring版本5.3.x以前
11.4.4.2、Spring版本5.3.x以后
本示例
11.5、环绕通知
11.5.1、配置环绕通知
环绕通知和动态代理的形式,非常相似
/**
* @Around注解:用于将方法标识为环绕