learn and grow up

解析springBean类的注解引发的一系列如AOP|cglib代理等问题四

字数统计: 396阅读时长: 2 min
2020/06/14 Share

写在前面

接上一篇,补充了第一篇最后提出解决方案中第三点的疑惑

疑惑&解答

经过研究发现果然是可以对cglib的对象进行反射获取到代理的对象,如下图

target

所以写了个简单的工具类,废话不多说,直接上代码:

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* 获取bean上的注解内容
* 注:springboot现动态代理默认为cglib,所以本方法只实现了cglib的获取
* @param <T>
* @param bean
* @param cls
* @return
*/
@Nullable
public static <T extends Annotation> T getAnnotationByBean(Object bean, Class<T> cls){
if(bean == null){
return null;
}

Object target = getTarget(bean);

return target.getClass().getAnnotation(cls);
}

/**
* 判断是不是springcglib代理类
* @param bean
* @return
*/
public static boolean checkIsCglibProxy(Object bean){
return bean.getClass().getName().contains("SpringCGLIB");
}

/**
* 获取代理类的代理对象,暂时只支持cglib代理类
* @param bean
* @return
*/
public static Object getTarget(Object bean){
if(!checkIsCglibProxy(bean)){
return bean;
}
String callBack="CGLIB$CALLBACK_0",advised="advised",target="target";
Object callBackBean,returnBean;

try {
callBackBean = getFieldValue(bean,callBack);
if(callBackBean == null){
return bean;
}
//尝试获取target
returnBean = getFieldValue(callBackBean,target);
if(returnBean!=null){
return returnBean;
}
//target为空,则获取advised
returnBean = getFieldValue(callBackBean,advised);
if(returnBean!=null){
if(returnBean instanceof AdvisedSupport){
try {
returnBean = ((AdvisedSupport) returnBean).getTargetSource().getTarget();
} catch (Exception e) {
log.error("cglib advised getTarget error",e);
return bean;
}
return returnBean;
}
}


} catch (IllegalAccessException e) {
log.error("cglib getTarget error",e);
return bean;
}
return bean;
}


/**
* 根据反射拿到object的fieldName值
* @param object
* @param fieldName
* @return
* @throws IllegalAccessException
*/
@Nullable
public static Object getFieldValue(Object object,String fieldName) throws IllegalAccessException {
if(object == null){
return null;
}
Field[] fields = object.getClass().getDeclaredFields();
for(Field field: fields){
String name = field.getName();
if(!fieldName.equals(name)){
continue;
}
field.setAccessible(true);
Object resultValue = field.get(object);
return resultValue;
}
return null;
}
CATALOG
  1. 1. 写在前面
  2. 2. 疑惑&解答