猿问

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

我需要能够找到 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(...)一切代价试图避免。


慕村225694
浏览 125回答 2
2回答

凤凰求蛊

一种可能的解决方案是实现 BeanPostProcessor。您可以在 bean 初始化之前访问底层类。这里的例子:@Componentpublic class ParametrizedBeanFactoryPostProcessor implements BeanPostProcessor {&nbsp; &nbsp; @Override&nbsp; &nbsp; public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {&nbsp; &nbsp; &nbsp; &nbsp; // bean is your actual class&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ("myBean".equals(beanName)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ParameterizedType pt = (ParameterizedType) bean&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getClass()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getMethod("doFoo", List.class)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getGenericParameterTypes()[0];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Class<?> listOfX = (Class<?>) pt.getActualTypeArguments()[0];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(listOfX); //class java.lang.Integer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } catch (NoSuchMethodException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return bean;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {&nbsp; &nbsp; &nbsp; &nbsp; // bean is proxy object&nbsp; &nbsp; &nbsp; &nbsp; return bean;&nbsp; &nbsp; }}

Smart猫小萌

看起来下面的代码在我的特定情况下可以找到底层的真实类:if&nbsp;(myBean&nbsp;instanceof&nbsp;org.springframework.aop.framework.Advised)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Class<?>&nbsp;realClass&nbsp;=&nbsp;((Advised)r).getTargetClass(); }从那里我可以使用标准反射。但我不确定这个解决方案是否合理,或者我是否可以期望所有 Spring bean 都实现该Advised接口。
随时随地看视频慕课网APP

相关分类

Java
我要回答