Спасибо всем (и особенно Эспену, которая приложила много усилий, чтобы показать мне различные варианты в Spring).
В итоге я сам нашел решение, которое не требует настройки Spring.
Я перешел по ссылке от Стивена С. Затем нашел ссылку на класс SimpleBeanInfo в этом наборе Threads. Этот класс позволяет пользователю написать свой собственный код разрешения метода bean, поместив другой класс в тот же пакет, что и класс, с нестандартными установщиками / получателями, чтобы переопределить логику с добавленным BeanInfo к имени класса и реализовать BeanInfo. 'интерфейс.
Затем я выполнил поиск в Google и нашел этот блог , который указал путь. Решение в блоге было довольно простым, поэтому я добавил его для своих целей.
на класс (с установщиками текучей среды)
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);
}
}
Метод генерации PropertyDescriptor
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.
- Просто, кажется, работает.
Недостатки этого подхода:
- Мне нужно создать класс BeanInfo для всех моих классов API с нестандартными установщиками. К счастью, таких классов всего около 10, и, переместив логику разрешения методов в отдельный класс, я могу поддерживать только одно место.
Заключительные мысли
По моему мнению, Spring должен изначально иметь дело с беглыми установщиками, они никому не вредят и должны просто игнорировать возвращаемое значение.
Требование, чтобы сеттеры были абсолютно недействительными, вынудило меня написать намного больше кода котельной пластины, чем мне было бы необходимо в противном случае. Я ценю спецификацию бина, но разрешение бина тривиально с использованием отражения, даже без использования стандартного распознавателя бина, поэтому Spring должен предложить опцию собственного распознавателя бина, который будет обрабатывать такие ситуации.
Конечно, оставьте стандартный механизм по умолчанию, но предложите вариант конфигурации в одну строку. Я с нетерпением жду будущих версий, где это может быть необязательно смягчено.