gpt4 book ai didi

java - Field.get(obj) 返回注入(inject)的 CDI 托管 bean 上的所有空值,同时手动调用 getter 返回正确的值

转载 作者:搜寻专家 更新时间:2023-11-01 02:43:01 24 4
gpt4 key购买 nike

我正在尝试通过反射从 JSF 页面的支持 bean 访问某些字段的值。问题是,当我使用 getter 时,我得到了正确的值,但是当我使用必要字段的 get(obj) 方法时,我总是得到返回的空值。

获取bean对象:

ELContext elcontext = FacesContext.getCurrentInstance().getELContext();
Object beanObject = FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elcontext, null, beanName);

要在不使用 getter 的情况下获取字段值,我执行以下操作:

List<Field> fields = new ArrayList<Field>();
ParamsBuilder.getAllFields(fields, beanClass);

for(Field field: fields) {

field.setAccessible(true);
System.out.println(field.getName() + ": " + field.get(beanObject)); //just to see if it works

}

getAllFields 方法有这样的实现:

public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
for (Field field: type.getDeclaredFields()) {
fields.add(field);
}

if (type.getSuperclass() != null) {
fields = getAllFields(fields, type.getSuperclass());
}

return fields;
}

要使用 getter 获取值,我执行以下操作:

private ClassX getValue(Object beanObject, Class<?> beanClass) throws Exception {

Method getter = beanClass.getDeclaredMethod("myMethod",(Class<?>[]) null);

return (ClassX)getter.invoke(beanObject, (Object[])null);
}

我可以进一步提到的是,我尝试访问的字段是用 @Inject 注释注入(inject)的,但我不认为这是问题,因为其他未注入(inject)的实例字段也会受到同样的影响。

通常我会使用 getter,但我在这里尝试做的事情对我正在开发的应用程序有全局影响,这意味着返回并修改所有受影响的类以提供 getter 是最后的措施解决方案。此外,此应用程序将不断修改和扩展,我不想利用其他开发人员不提供 getter 的机会,这将导致严重的问题。

谢谢!

最佳答案

这确实是预期的行为。 CDI 托管 bean 实例本质上是一个自动生成类的可序列化代理实例,它扩展了原始支持 bean 类,并通过公共(public)方法将所有公共(public)方法进一步委托(delegate)给实际实例(就像 EJB 的工作方式一样)。自动生成的类大致如下所示:

public CDIManagedBeanProxy extends ActualManagedBean implements Serializable {

public String getSomeProperty() {
ActualManagedBean instance = CDI.resolveItSomehow();
return instance.getSomeProperty();
}

public void setSomeProperty(String someProperty) {
ActualManagedBean instance = CDI.resolveItSomehow();
instance.setSomeProperty(someProperty);
}

}

如您所见,没有具体的字段。在检查类本身时,您还应该注意到自动生成的类签名。

毕竟,您的做法是错误的。你应该使用 java.beans.Introspector API内省(introspection) bean 并在 bean 实例上调用 getter/setter。

这是一个启动示例:

Object beanInstance = getItSomehow();
BeanInfo beanInfo = Introspector.getBeanInfo(beanInstance.getClass());

for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
String name = property.getName();
Method getter = property.getReadMethod();
Object value = getter.invoke(beanInstance);
System.out.println(name + "=" + value);
}

此 API 像 JSF 和 CDI 一样尊重 JavaBeans spec ,因此您无需摆弄原始反射 API 并计算/猜测正确的方法名称。


与具体问题无关,具体取决于具体的功能需求,您可能错误地认为这一切都是正确的解决方案,而您在问题中没有提及任何内容,那里可能是比内省(introspection) bean 实例更好的实现方法。

关于java - Field.get(obj) 返回注入(inject)的 CDI 托管 bean 上的所有空值,同时手动调用 getter 返回正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29651008/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com