CGLIB注解丢失原因浅析及解决办法

CGLIB动态代理后注解无法获取

今天在开发中,使用了Srping的cglib,偶尔发现若开启CGLIB代理 spring.aop.proxy-target-class=true注入接口后无法获取其实现类上注解@service。

通过debug得到class文件名含有EnhancerBySpringCGLIB:

com.xxx.service.impl.xxxxImpl$$EnhancerBySpringCGLIB$$f69341ff

并clazz.getAnnotation();得到注解为空。

原因浅析

我们首先来看看 @Inherited:
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。 也就是说如果没有@Inherited,该注解将不会用于子class。

注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation, 方法并不从它所实现的方法继承annotation。

另外, 当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

cglib的enhancer 为我们生成了一个在xxxxImpl的基础上的增强类,class在实际运行时候的Class对象已经不是原本的class了,又因为@service没有被@Inherited修饰,所以注解丢失了。

解决办法:

  1. 将spring.aop.proxy-target-class=true 去掉, 自动使用JDK代理。
  2. 使用 org.springframework.core.annotation.AnnotationUtils;
    AnnotationUtils.getAnnotation(),但是有个缺陷是此方法只能获取类及方法上的注解,无法获取属性成员的注解。
  3. 使用@Inherited的方式(由于没有尝试过不清楚可行性,仅贴链接供参考):
    https://www.cnblogs.com/hujunzheng/p/8433980.html
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值