感谢所有人(特别是Espen,他付出了很多努力向我展示了春季的各种选择)。
最后,我自己找到了一个不需要Spring配置的解决方案。
我点击了Stephen C的链接,然后在那组线程中找到了对SimpleBeanInfo类的引用。该类允许用户编写自己的Bean方法解析代码,方法是将另一个类放在与具有非标准 setters/getters 的类相同的包中,以覆盖将“BeanInfo”附加到类名上的逻辑并实现“BeanInfo”接口。
然后我在谷歌上搜索了一下,找到了这个指出了方向的博客。博客上的解决方案非常基本,所以我为了我的目的而填充了它。
每班(流利的二传手)
public class MyComponentBeanInfo<T> extends SimpleBeanInfo {
private final static Class<?> _clazz = MyComponent.class;
PropertyDescriptor[] _properties = null;
public synchronized PropertyDescriptor[] getPropertyDescriptors() {
if (_properties == null) {
_properties = Helpers.getPropertyDescriptionsIncludingFluentSetters(_clazz);
}
return _properties;
}
public BeanDescriptor getBeanDescriptor() {
return new BeanDescriptor(_clazz);
}
}
属性描述符生成方法
public static PropertyDescriptor[] getPropertyDescriptionsIncludingFluentSetters( Class<?> clazz) {
Map<String,Method> getterMethodMap = new HashMap<String,Method>();
Map<String,Method> setterMethodMap = new HashMap<String,Method>();
Set<String> allProperties = new HashSet<String>();
PropertyDescriptor[] properties = null;
try {
Method[] methods = clazz.getMethods();
for (Method m : methods) {
String name = m.getName();
boolean isSetter = m.getParameterTypes().length == 1 && name.length() > 3 && name.substring(0,3).equals("set") && name.charAt(3) >= 'A' && name.charAt(3) <= 'Z';
boolean isGetter = (!isSetter) && m.getParameterTypes().length == 0 && name.length() > 3 && name.substring(0,3).equals("get") && name.charAt(3) >= 'A' && name.charAt(3) <= 'Z';
if (isSetter || isGetter) {
name = name.substring(3);
name = name.length() > 1
? name.substring(0,1).toLowerCase() + name.substring(1)
: name.toLowerCase();
if (isSetter) {
setterMethodMap.put(name, m);
} else {
getterMethodMap.put(name, m);
}
allProperties.add(name);
}
}
properties = new PropertyDescriptor[allProperties.size()];
Iterator<String> iterator = allProperties.iterator();
for (int i=0; i < allProperties.size(); i++) {
String propertyName = iterator.next();
Method readMethod = getterMethodMap.get(propertyName);
Method writeMethod = setterMethodMap.get(propertyName);
properties[i] = new PropertyDescriptor(propertyName, readMethod, writeMethod);
}
} catch (IntrospectionException e) {
throw new RuntimeException(e.toString(), e);
}
return properties;
}
这种方法的优点:
- 没有自定义弹簧配置(Spring不知道非标准设置器,并将其视为正常)。不依赖于任何Spring.jar文件,但可以从Spring访问。
- 似乎只是工作。
这种方法的缺点:
- 我必须为我的所有API类创建一个BeanInfo类,其中包含非标准设置器。幸运的是,只有大约10个这样的类,通过将方法解析逻辑移动到一个单独的类中,我只有一个地方可以维护。
结束语
在我看来,Spring应该天生地处理流利的二传手,他们不会伤害任何人,它应该忽略返回值。
通过要求 setter 严格无效,它迫使我编写比我需要的更多的样板代码。我很欣赏Bean规范,但是使用反射甚至不使用标准Bean解析器即可实现bean分辨率,因此Spring应该提供自己的Bean解析器选项来处理这种情况。
无论如何,将标准机制保留为默认机制,但提供单行配置选项。我期待着未来的版本,其中可能会有所选择的放松。