为了账号安全,请及时绑定邮箱和手机立即绑定

找不到获取 Spring bean 方法参数的参数化类型的方法

找不到获取 Spring bean 方法参数的参数化类型的方法

慕村225694 2023-07-13 17:35:20
我需要能够找到 Spring bean 上方法参数的参数化类型。我正在使用 Spring Boot 2.0.1。我有一个 Spring bean,如下所示:public class MyBean {   public void doFoo(List<Integer> param) {...}}我需要能够找出参数的参数化类型param。通常我可以这样做:MyBean myBean = getMyBean();ParameterizedType pt = (ParameterizedType)myBean   .getClass()   .getMethod("doFoo", List.class)   .getGenericParameterTypes()[0];Class<?> listOfX = (Class<?>)pt.getActualTypeArguments()[0];但是,当针对 Spring bean 执行此操作时,该getGenericParameterTypes()方法始终返回对象数组Class而不是对象数组Type。原因是 Spring 广泛使用 CGLIB 来提供类的运行时重新编译以支持 AOP。因此,我没有获取 的实例MyBean,而是获取 的实例MyBean$$EnhancerBySpringCGLIB$$xxxxxxxx,并且“重新编译”的类丢失了所有泛型信息(显然是因为 CGLIB 是在泛型存在之前编写的,并且不再受到积极支持?)。如果仅提供 Spring bean 实例,我可以使用一些想法来了解如何获取此参数的参数化信息。MyBean.class我一直在尝试寻找从那里访问的方法,MyBean$$EnhancerBySpringCGLIB$$xxxxxxxx并从那里找到我可以使用反射的真正方法。但我还没有找到解决办法。我正在不惜Class.forName(...)一切代价试图避免。
查看完整描述

2 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

一种可能的解决方案是实现 BeanPostProcessor。您可以在 bean 初始化之前访问底层类。


这里的例子:


@Component

public class ParametrizedBeanFactoryPostProcessor implements BeanPostProcessor {


    @Override

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        // bean is your actual class

        try {

            if ("myBean".equals(beanName)) {

                ParameterizedType pt = (ParameterizedType) bean

                        .getClass()

                        .getMethod("doFoo", List.class)

                        .getGenericParameterTypes()[0];


                Class<?> listOfX = (Class<?>) pt.getActualTypeArguments()[0];

                System.out.println(listOfX); //class java.lang.Integer

            }

        } catch (NoSuchMethodException e) {

            e.printStackTrace();

        }

        return bean;

    }


    @Override

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        // bean is proxy object

        return bean;

    }

}


查看完整回答
反对 回复 2023-07-13
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

看起来下面的代码在我的特定情况下可以找到底层的真实类:

if (myBean instanceof org.springframework.aop.framework.Advised) {
    Class<?> realClass = ((Advised)r).getTargetClass();
}

从那里我可以使用标准反射。但我不确定这个解决方案是否合理,或者我是否可以期望所有 Spring bean 都实现该Advised接口。


查看完整回答
反对 回复 2023-07-13
  • 2 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信