通知(方法)
* 环绕通知(方法)使用的参数是ProceedingJoinPoint类型
* 环绕通知(方法)的返回值,必须和目标对象方法的返回值一致
*/
@Around("pointCutOne()")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] args = proceedingJoinPoint.getArgs();
Object result = null;
try {
System.out.println("LoggerAspect-->环绕前置通知,方法名:"+methodName+",参数:"+ Arrays.toString(args));
// 表示目标对象方法的执行
result = proceedingJoinPoint.proceed();
System.out.println("LoggerAspect-->环绕返回通知,方法名:"+methodName+",结果:"+ result);
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("LoggerAspect-->环绕异常通知,方法名:"+methodName+",异常:"+ throwable);
}finally {
System.out.println("LoggerAspect-->环绕后置通知,方法名:"+methodName+",参数:"+ Arrays.toString(args));
}
return result;
}
11.5.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.6、切面的优先级
11.6.1、创建其他切面类ValidateAspect
package org.rain.spring.aop.annotation;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
/**
* @author liaojy
* @date 2023/8/15 - 7:49
*/
@Aspect
@Component
public class ValidateAspect {
}
11.6.2、配置前置通知方法
@Before("org.rain.spring.aop.annotation.LoggerAspect.pointCutOne()")
public void beforeMethod(){
System.out.println("ValidateAspect-->前置通知");
}
11.6.3、测试使用效果
由控制台日志可知,ValidateAspect切面的前置通知方法生效了,但执行顺序在LoggerAspect切面的前置通知方法的后面
@Test
public void testAOPByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-aop-annotation.xml");
// 虽然不知道代理对象的类名,但可以通过代理对象和目标对象共同实现的接口类型来从ioc容器中获取代理对象
Calculator calculator = ioc.getBean(Calculator.class);
// 只能通过代理对象来访问目标对象中的方法
calculator.div(1,1);
}
11.6.4、调整切面的优先级
package org.rain.spring.aop.annotation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author liaojy
* @date 2023/8/15 - 7:49
*/
@Aspect
@Component
// @Order注解:用于设置切面的优先级,value属性值越小,优先级越高,默认值为Integer的最大值
@Order(2023)
public class ValidateAspect {
@Before("org.rain.spring.aop.annotation.LoggerAspect.pointCutOne()")
public void beforeMethod(){
System.out.println("ValidateAspect-->前置通知");
}
}
11.6.5、测试调整后的效果
由控制台日志可知,ValidateAspect切面的前置通知方法的执行顺序,在LoggerAspect切面的前置通知方法的前面
这是因为ValidateAspect切面的@Order注解的value属性值已设为2023,要小于LoggerAspect切面所使用的默认值(Integer的最大值2147483647)
11.7、扩展知识