AspectJ
maven依赖:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
1. AspectJ 简介
AspectJ是一个面向切面的框架,它扩展了Java语言,定义了AOP 语法,能够在编译期提供代码的织入。Spring通过集成AspectJ实现了以注解的方式定义增强类,大大减少了配置文件中的工作量。
2. AspectJ 注解
- @Aspect 切面标识 (类注解)
- @Before 前置通知(方法注解)
- @AfterReturning 后置通知(方法注解)
- @Around 环绕通知(方法注解)
- @AfterThrowing 异常抛出通知(方法注解)
- @After 最终通知(方法注解)
3. 开启注解支持
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--需要产生通知的切面类-->
<bean id="userService" class="com.dream.spring.aop.service.impl.UserServiceImpl"></bean>
<!--AspectJAdvice将放入ioc容器-->
<bean class="com.dream.spring.aop.advice.AspectJAdvice" />
<!--开启AspectJ的注解支持-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
4. 编写 AspectJAdvice 类
@Aspect
public class AspectJAdvice {
@Before(value = "execution(* com.dream.spring.aop.service..*(..))")
public void before(JoinPoint jp){
Object[] args = jp.getArgs(); //获取方法参数
Signature signature = jp.getSignature(); //获取签名
if(signature instanceof MethodSignature){ //如果签名是方法签名
Method method = ((MethodSignature) signature).getMethod(); //获取方法
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
System.out.println("AspectJ准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args));
}
}
@AfterReturning(value = "execution(* com.dream.spring.aop.service..*(..))", returning = "returnValue")
public void after(JoinPoint jp, Object returnValue){
Object[] args = jp.getArgs(); //获取方法参数
Signature signature = jp.getSignature(); //获取签名
if(signature instanceof MethodSignature){ //如果签名是方法签名
Method method = ((MethodSignature) signature).getMethod(); //获取方法
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
System.out.println("AspectJ执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue);
}
}
@AfterThrowing(value = "execution(* com.dream.spring.aop.service..*(..))", throwing = "t")
public void exception(JoinPoint jp, Throwable t){
Object[] args = jp.getArgs(); //获取方法参数
Signature signature = jp.getSignature(); //获取签名
if(signature instanceof MethodSignature){ //如果签名是方法签名
Method method = ((MethodSignature) signature).getMethod(); //获取方法
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
System.out.println("AspectJ执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage());
}
}
@Around("execution(* com.dream.spring.aop.service..*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();//获取方法的参数
Object target = pjp.getTarget(); //获取代理对象
Signature signature = pjp.getSignature(); //获取签名
if(signature instanceof MethodSignature) { //如果签名是方法签名
Method method = ((MethodSignature) signature).getMethod(); //获取被拦截的方法对象
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
try {
System.out.println("AspectJ准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args));
Object returnValue = method.invoke(target, args);
System.out.println("AspectJ执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue);
return returnValue;
} catch (Throwable t){
System.out.println("AspectJ执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage());
throw t;
} finally {
System.out.println("最终通知");
}
}
return null;
}
}