当前位置:首页 » 《关注互联网》 » 正文

【上】java获取requestMapping上所有注解功能实现及取匿名注释类的值及 class com.sun.proxy.$Proxy140 转换出错

23 人参与  2024年09月14日 10:02  分类 : 《关注互联网》  评论

点击全文阅读


java获取requestMapping上所有注解功能实现及取匿名注释类的值及 class com.sun.proxy.$Proxy140 转换出错

1,多人相当然以为类似对象一样直接强转下就可以,结果迎来的是class com.sun.proxy.$Proxy140转换出错【想法很勇敢,现实很骨感】
//Class<A> operatorMappingAnnotationType// 错误示例OperatorMapping operatorMapping = (OperatorMapping)method.getMethodAnnotation(operatorMappingAnnotationType);

实质上会抛出 不能转换代理相关报错的,所以还是另辟蹊径吧,少年。

2,业务场景:

在开发过程中需要写一个插件或者小功能,需要根据不同的匿名的注释类来获取该注释下的相关内容,如:获取controller上的某注解的内容(该注解可能A项目是 @***A, B项目可能是@***B。。。。)或者直接传入类地址, 那么在具体实现的插件下面是完全不知道这个注解到底是哪个,但是又要在插件中去把 注解里面的内容给拿出来给调用方使用

3,在Java中,如果你需要访问动态代理类(如com.sun.proxy.$Proxy140)中的属性和值,你通常不能直接这么做,因为这些类是由Java运行时动态生成的,它们的属性和方法是私有的,不应该直接访问。

然而,如果你需要获取这些代理对象的一些信息,你可以使用反射来间接地获取。这里有一个例子,展示了如何使用反射来访问代理对象的一些信息:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import java.lang.reflect.Field; public class ProxyInspector {    public static void main(String[] args) throws Exception {        // 假设你有一个代理对象的实例,名为proxy        Object proxy = ...; // 这里应该是你的$Proxy140实例         // 获取代理的InvocationHandler        InvocationHandler handler = Proxy.getInvocationHandler(proxy);         // 通过反射获取InvocationHandler的字段        Field hField = handler.getClass().getDeclaredField("h");        hField.setAccessible(true); // 设置为可访问         // 获取代理的实际对象        Object proxyTarget = hField.get(handler);         // 现在你可以对proxyTarget做你想做的任何反射操作        // 例如,获取它的属性值        Field someField = proxyTarget.getClass().getDeclaredField("someFieldName");        someField.setAccessible(true);        Object fieldValue = someField.get(proxyTarget);         System.out.println("Field value: " + fieldValue);    }               }

请注意,这种方法依赖于com.sun.proxy.$Proxy类的内部实现,它可能会在不同版本的JDK中发生变化,因此可能不是一个可移植或可靠的解决方案。此外,访问私有字段也违反了封装的原则,应当谨慎使用。

如果你需要这样的功能,通常意味着你的设计可能有改进的空间。例如,你可以考虑将必要的信息直接暴露给代理对象,或者使用一个不会造成这种情况的设计模式。

4,实际业务实例如下:
/**     * 获取代理的InvocationHandler 具体得  实际对象内容     * @version 2024-9-217:36:26     * @author zj     * @param <A>     * @param method     * @param operatorMappingAnnotationType     * @param invocationHandlerField 获取代理的得指定字段属性名     * @return     */    @SuppressWarnings("unchecked")    public <A extends Annotation> Map<String, Object> getInvocationHandlerData(HandlerMethod method, Class<A> operatorMappingAnnotationType, String invocationHandlerField) {        Map<String, Object> proxyTarget = new HashMap<String, Object>();        try {            String operatorMappingSrc = menuConfigProperties.getOperatorMappingSrc();            Object proxy = null;            if (operatorMappingAnnotationType != null) {                proxy = method.getMethodAnnotation(operatorMappingAnnotationType);            } else {                // 获取对应类的class                Class<A> operatorMappingNameClass = (Class<A>) Class.forName(operatorMappingSrc);                proxy =  method.getMethodAnnotation(operatorMappingNameClass);            }            if (proxy == null) {                return proxyTarget;            }            // 获取代理的InvocationHandler            InvocationHandler handler = Proxy.getInvocationHandler(proxy);            Class<? extends InvocationHandler> handlerClass = handler.getClass();            // 指定的Annotation 的  memberValues 获取值              Field declaredField = handlerClass.getDeclaredField(invocationHandlerField);            declaredField.setAccessible(true);            // 获取代理的实际对象            proxyTarget = (Map<String, Object>)declaredField.get(handler);            log.info("getInvocationHandlerData proxyTarget = {}", proxyTarget);                        // 方式2 //            A operatorMappingMethodAnnotation =  method.getMethodAnnotation(operatorMappingAnnotationType);//            Class<? extends Annotation> annotationType = operatorMappingMethodAnnotation.annotationType();//            Method[] declaredMethods = annotationType.getDeclaredMethods();//            for (Method methodItem : declaredMethods) {//                Object value = handler.invoke(proxy, methodItem, null);//                String name = methodItem.getName();//                log.info("name={}, value = {}", name, value);//            }        } catch (Exception e1) {            log.error("getInvocationHandlerData {}", e1);        }        return proxyTarget;    }

5,完整实现代码可看下篇:

进微信交流群可联系V:q1227260341,备注加java群

。。。。。


点击全文阅读


本文链接:http://zhangshiyu.com/post/159635.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1