すべての人 (特に、Spring 内のさまざまなオプションを示すために多大な努力を払ってくれた Espen) に感謝します。
結局、Spring 構成を必要としない解決策を自分で見つけました。
Stephen C のリンクをたどると、そのスレッドのセット内に SimpleBeanInfo クラスへの参照が見つかりました。このクラスを使用すると、ユーザーは独自の 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 は非標準のセッターを認識せず、それらを通常と見なします)。Spring .jar ファイルには依存しませんが、Spring からアクセスできます。
- ただうまくいくようです。
このアプローチの欠点:
- 非標準のセッターを使用して、すべての API クラスに BeanInfo クラスを作成する必要があります。幸いなことに、そのようなクラスは約 10 個しかなく、メソッド解決ロジックを別のクラスに移動することで、維持する場所が 1 つだけになりました。
最後に
私の意見では、Spring は流暢なセッターをネイティブに処理する必要があります。それらは誰も傷つけず、戻り値を無視するだけです。
セッターが厳密に無効であることを要求することで、そうでない場合よりも多くの定型コードを作成する必要がありました。Bean 仕様には感謝していますが、Bean の解決は、標準の Bean リゾルバーを使用しなくてもリフレクションを使用すると簡単なので、Spring はこの状況を処理する独自の Bean リゾルバーのオプションを提供する必要があります。
必ず、標準のメカニズムをデフォルトのままにしておきますが、1 行の構成オプションを提供してください。これがオプションで緩和される将来のバージョンを楽しみにしています。