对一个Autowired进来的类调用getClass,发现得到的类是:”com.xxx.search.provider.service.SearchServiceImpl$$EnhancerBySpringCGLIB$$129db519”,一看就不是正经类。从名字中可以看出,这个是被代理后的类,可能因为这个类被AOP了吧。但是我在反射操作是需要原始的类的信息,要如何得到呢?

org.springframework.aop下有一个很重要的接口:TargetClassAware,这个接口表示目前这个类是被代理的。所以我们可以通过判断一个实例是否是TargetClassAware的实例来判断他是否是一个代理类。而且TargetClassAware接口提供了getTargetClass方法来获取真实类。可以这么用:

1
2
3
if(aInstance instanceof TargetClassAware){
aInstance.getTargetClass();
}

不过更推荐的做法是使用org.springframework.aop.support.AopUtils提供的getTargetClass方法来获取真实类。可以看看其源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static Class<?> getTargetClass(Object candidate) {
Assert.notNull(candidate, "Candidate object must not be null");
Class result = null;
if(candidate instanceof TargetClassAware) {
result = ((TargetClassAware)candidate).getTargetClass();
}

if(result == null) {
result = isCglibProxy(candidate)?candidate.getClass().getSuperclass():candidate.getClass();
}

return result;
}

代码首先判断当前类是否是TargetClassAware的实现,如果是,调用getTargetClass,方法还判断当前类是否是CglibProxy,如果是基于cglib的代理类,因为是基于继承来实现代理,所以获取父类就是真实类了。

参考资料