Spring AOP自定义注解

自定义注解

Posted by John Doe on 2020-10-07
Words 494 and Reading Time 2 Minutes
Viewed Times

自定义注解类

1
2
3
4
5
6
7
8
9
10
11
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.TYPE, ElementType.METHOD})//使用位置(类,方法)
@Retention(RetentionPolicy.RUNTIME)//加载到jvm里运行
public @interface MyAspect {
String value(); //注解的属性,如果只有一个属性,一般叫value
String name() default ""; //属性,默认值"",可以不写
}

切面类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect//来定义一个切面
@Component
public class MyAspectAop {

//定义切入点
@Pointcut("@annotation(com....MyAspect)")
public void auditAspect() {

}

//通知
@Before("auditAspect()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("触发到 @Before(\"auditAspect()\")");
}

/**
* 后置通知 @Around环绕处理
*
* @param joinPoint 切点
*/
@AfterReturning("auditAspect()")
public void doAfrterReturning(JoinPoint joinPoint) {

Object[] args = joinPoint.getArgs();
System.out.println("触发 @AfterReturning(\"auditAspect()\")");
System.out.println(args.length);
getControllerMethodDescription(joinPoint);
}

/**
* 获取注解中对方法的描述信息
*
* @param joinPoint 切点
* @return 方法描述
*/
public static void getControllerMethodDescription(JoinPoint joinPoint) {
String targetName = joinPoint.getTarget().getClass().getName(); //获得执行方法的类名
String methodName = joinPoint.getSignature().getName(); //获得执行方法的方法名
Object[] arguments = joinPoint.getArgs(); //获取切点方法的所有参数类型
try {
Class targetClass = Class.forName(targetName);

Method[] methods = targetClass.getMethods(); //获取公共方法,不包括类私有的
String value = "";
String name = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes(); //对比方法中参数的个数
if (clazzs.length == arguments.length) {
value = method.getAnnotation(MyAspect.class).value();
name = method.getAnnotation(MyAspect.class).name();
break;
}
}
}
System.out.println("value=" + value);
System.out.println("name=" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
}

注解使用

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 测试自定义注解
*/
@MyAspect(value = "MyAspect", name = "name")
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add() {
//获取本服务的信息
ServiceInstance instance = client.getLocalServiceInstance();
Integer r = 2;
String info = "/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + "结果:" + r;
logger.info(info);
return info;
}

结果

1
2
3
4
5
6
触发到 @Before("auditAspect()")
2018-09-13 20:11:07.554 INFO 14012 --- [nio-9003-exec-1] c.c.s.c.ComputeController@7fcff1b9 : /add, host:localhost, service_id:MyAspect-service结果:2
触发 @AfterReturning("auditAspect()")
0
value=MyAspect
name=name

This is copyright.

...

...

00:00
00:00