cglib动态代理导致注解丢失问题及如何修改注解允许被继承

简介: 现象   SOAService这个bean先后经过两个BeanPostProcessor,会发现代理之后注解就丢失了。         开启了cglib代理 @SpringBootApplication @EnableAspectJAutoProxy(proxyTargetClass...

现象

  SOAService这个bean先后经过两个BeanPostProcessor,会发现代理之后注解就丢失了。

  

    

开启了cglib代理

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.run(args);
    }
}

为什么开启这个代理模式呢

  http://www.cnblogs.com/hujunzheng/p/8428422.html 

如何解决这个问题

  在自定义注解上添加@Inherited。如果是第三方的注解,调整项目接口层或者拿到这个注解通过代码方式加上@Inherited注解, 或者如下图所示。

  

 

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    Service anon = bean.getClass().getAnnotation(Service.class);
    if (anon != null) {
        try {
            InvocationHandler h = Proxy.getInvocationHandler(anon);

            //设置@Service注解支持继承,应对动态代理导致类上的@Service注解丢失
            Field typeField = h.getClass().getDeclaredField("type");
            typeField.setAccessible(true);
            Field annotationTypeField = Class.class.getDeclaredField("annotationType");
            annotationTypeField.setAccessible(true);
            AnnotationType annotationType = (AnnotationType) annotationTypeField.get(typeField.get(h));
            Field inheritedField = AnnotationType.class.getDeclaredField("inherited");
            this.updateFinalModifiers(inheritedField);
            inheritedField.set(annotationType, true);

            // 获取 AnnotationInvocationHandler 的 memberValues 字段
            Field memberValuesField = h.getClass().getDeclaredField("memberValues");
            // 因为这个字段事 private final 修饰,所以要打开权限
            memberValuesField.setAccessible(true);
            // 获取 memberValues
            Map memberValues = (Map) memberValuesField.get(h);

            Service service = Stream.of(bean.getClass().getInterfaces())
                    .filter(iface -> iface.getAnnotation(Service.class) != null)
                    .collect(Collectors.toList())
                    .get(0)
                    .getAnnotation(Service.class);

            memberValues.put("version", service.version());
            memberValues.put("group", service.group());
        } catch (Exception e) {
            throw new BeanCreationException(String.format("%s %s %s %s %s"
                        , "修改"
                        , ClassUtils.getQualifiedName(bean.getClass())
                        , "的注解"
                        , ClassUtils.getQualifiedName(Service.class)
                        , "的 group值和version值出错")
                    , e);
        }
    }
    return bean;
}

 

  参考链接:Annotation和动态代理

目录
相关文章
|
机器学习/深度学习 人工智能 文字识别
CRNN文字识别
近几年来,CRNN在计算机视觉文本识别领域取得不错成果。CRNN是一种卷积循环神经网络结构,用于解决基于图像的序列识别问题,特别是场景文字识别问题。CRNN网络实现了不定长验证结合CNN和RNN网络结构,使用双向LSTM循环网络进行时序训练,并在最后引入CTC损失函数来实现端对端的不定长序列识别,
1610 0
CRNN文字识别
解决 Vant中 输入框(Field)组件获取不到输入值
解决 Vant中 输入框(Field)组件获取不到输入值
2330 0
解决 Vant中 输入框(Field)组件获取不到输入值
|
9月前
|
开发工具 git
git 使用之remote: File [4e21e71a555febaa4dfaaa05cf7eeb606ea96ae2] size 104.090MB, exceeds quota 100MB remote: Please remove the file[s] from history and try again 报错如何解决-优雅草卓伊凡
git 使用之remote: File [4e21e71a555febaa4dfaaa05cf7eeb606ea96ae2] size 104.090MB, exceeds quota 100MB remote: Please remove the file[s] from history and try again 报错如何解决-优雅草卓伊凡
763 3
git 使用之remote: File [4e21e71a555febaa4dfaaa05cf7eeb606ea96ae2] size 104.090MB, exceeds quota 100MB remote: Please remove the file[s] from history and try again 报错如何解决-优雅草卓伊凡
|
10月前
|
Java 开发者 Spring
java springboot监听事件和处理事件
通过上述步骤,开发者可以在Spring Boot项目中轻松实现事件的发布和监听。事件机制不仅解耦了业务逻辑,还提高了系统的可维护性和扩展性。掌握这一技术,可以显著提升开发效率和代码质量。
365 13
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
651 1
|
Java
Waited 3000 milliseconds (plus 110349 nanoseconds delay) for com.alibaba.nacos.shaded.io.grpc.stub.ClientCalls
Waited 3000 milliseconds (plus 110349 nanoseconds delay) for com.alibaba.nacos.shaded.io.grpc.stub.ClientCalls
2014 0
|
NoSQL Redis
redis序列化问题:invalid stream header
redis序列化问题:invalid stream header
1038 0
|
Java 应用服务中间件
IDEA Error:(7, 26) java: 程序包javax.servlet.http不存在
IDEA Error:(7, 26) java: 程序包javax.servlet.http不存在
3207 0
IDEA Error:(7, 26) java: 程序包javax.servlet.http不存在
|
SQL Java 数据库连接
Hibernate 和 JPA 有什么区别?
【8月更文挑战第21天】
917 0