Spring Beanの自動キャスト
質問
Spring BeanをアプリケーションコンテキストXMLで定義されたクラスに自動キャストする方法はありますか? Beanの型情報を2つの場所に配置しないようにしたいのですが...
たとえば、この設定ファイルを指定
<bean id="bean-name" class="SimpleSpringBean" scope="prototype">
<property name="myValue" value="simple value"></property>
</bean>
戻り値の型を SimpleStringBean
に直接キャストしないように、 ApplicationContext.getBean(&quot; bean-name&quot;)
を呼び出すことができます。 ApplicationContext.getBean(&quot; bean-name&quot ;, SimpleSpringBean.class)
を呼び出してキャスト自体を回避することもできますが、2つの場所に型情報があります。
Springはクラス情報( ApplicationContext.getType
)を取得するか、Bean自体から型を取得することができますが、プログラマーの介入なしで型を自動的にキャストする方法はありません。
解決
Siiに同意します。getBeanをできる限り呼び出さないでください。 Beanをそれらに依存するクラスに配線するだけです。
それでも、アプリケーションコンテキストを保持する単一のクラスがある場合、次のようなラッパージェネリックメソッドを提供できます。
class MyContextHolder{
ApplicationContext appContext;
......
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName)
{
return (T)appContext.getBean(beanName);
}
}
その後、キャストせずに呼び出すことができます
MyClass mc = MyContextHolder.getBean("myClassBean");
他のヒント
答えは、可能であればApplicationContext.getBean()を使用するべきではなく、ブートストラップコード内で必要な1つの場所を使用することです。 (一般に、アプリケーションのエントリポイント以外ではgetBean()を使用する必要はありません。)
また、あなたが求めていることは、おそらくJava言語ではまったく不可能です。キャストはコンパイル時の機能であり、ランタイムチェックと組み合わされています。 getBean()の戻り値の型は、コンパイル時に既知である必要があります。 Springがオブジェクトのタイプを判別できたとしても、実行時に独自のメソッドシグネチャを変更することはできません。
別のことは、これが可能であったとしても、この機能はそれほど有用ではないということです。 Spring AOPは動的プロキシを使用して実装されているため、ほとんどの場合、Springに、実装クラスではなく、Beanが実装するインターフェース(AOPプロキシの場合もあります)のインスタンスを渡す必要があります。
私が使用している別のアプローチは、次を使用してブートストラップクラスを自動配線することです。
public class Main {
@Autowired FooFacade foo;
@Autowired BarFacade bar;
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
Object main = bf.createBean(Main.class,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
false);
((Main) main).run();
}
private void run() {
foo.doBootstrapStuff();
bar.doMoreBootstrapStuff();
}
}
(メモリから実行されるコード。Springコンテキストが配線注釈を処理するように構成されている場合にのみ機能する可能性があります。その場合、 foo
および bar
のセッターの作成は機能するはずです。 )
getBean
が型指定されていない主な理由は、Spring(バージョン2.5.xまで)とJava 1.4との互換性です。 Spring 3.0はそれをドロップし、型指定された getBean
メソッドを提供します。
それでも、Beanを直接検索することは避け、可能な限りその使用を最小限に抑える必要があります。
アプリケーションが広範囲に使用するオブジェクトファクトリとしてSpringを使用するとどうなりますか。 つまり、すでに継承またはラップアラウンドするクラスの束を書く代わりに 既知のJavaクラスすべてを削減するためにすべてをxmlファイルに移動することにしました Javaコードの行。これはxmlの多くの行を意味しますが、私は作る必要はありません Springまたはautowireで注入するスケルトンJavaクラス。したがって、線を作る Javaコードレス。
このため、まだSpringを初めて使用するときは、前に述べたように 投稿では、getBeans()をラップする静的Javaメソッドを使用しました。
Springで作業したことがありますが、まだ新しいので質問をお許しください。
&quot; Spring AOPは動的プロキシを使用して実装されるため、ほとんどの場合、Springに、実装クラスではなく、Beanが実装するインターフェイスのインスタンス(AOPプロキシである可能性があります)を渡す必要があります。
では、getBean()を使用して動的プロキシを取得する方法はありません。次に、インターフェイスがなく、実行するスタンドアロンのドライバクラスがない場合のベストプラクティスは何ですか?