スプリングは、ビンの形で管理できないいくつかのオブジェクトを
ビンに活用できるよう、FactoryBean機能を提供しております。
文字通りBeanを抜き出す工場の役割をするクラスです。
サンプルコードをご覧ください。。
構成はこのようです。
expressというメッセージを込めているオブジェクトをFactoryBeanから作り上げます。
xmlはSpringの注入に必要な設定をしてくれるファイルで
Testは、テストクラスです。
public class express {
String express;
private express(String express) {
this.express = express;
}
public String getExpress() {
return express;
}
public static express newMessage(String express) {
return new express(express);
}
}
まず、モデルクレスあるexpressクラスです。
getterがあり、コンストラクタがあります。
呼び出した時、新しいインスタンスを返すためにstaticメソッドがあるのが特徴です。
package proxy2;
import org.springframework.beans.factory.FactoryBean;
public class ExpressFactoryBean implements FactoryBean<express> {
String expressFactory;
public void setExpressFactory(String expressFactory) {
this.expressFactory = expressFactory;
}
@Override
public express getObject() throws Exception {
return express.newMessage(this.expressFactory);
}
@Override public Class<? extends express> getObjectType() {
return express.class;
}
@Override public boolean isSingleton() {
return true;
}
}
ExpressFactoryBeanクラスです。
FactoryBean機能を実装するために、
ジェネリッククラスであるインターフェースを実装する必要があります。
expressFactoryメンバ変数とsetterを除けば
下のoverrideメソッド三つが実装すべきメソッドです。
最初は工場で新しいオブジェクトを作り上げ返すように
getを使いexpressオブジェクトを戻してくれるメソッドです。
getObjectTypeメソッドは実装したクラスを返してくれるメソッドです。
isSingletoneメソッドは、生成されたオブジェクトを
シングルトン(一つのオブジェクト)に設定するかを定めるメソッドです
trueを返せば、アドレスのデータをリサイクルし、falseを返せば、毎回再作成します。
以下はxmlファイルです。
<bean id="express" class="proxy2.ExpressFactoryBean">
<property name="expressFactory" value="express value" />
</bean>
xmlファイルには、
FactoryBeanクラスのexpressFactory変数にexpressという文字列を注入しています。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:proxy2/FactoryBeanTest-context.xml") // FactoryBeanTest-context.xml Auto Referencing
public class FactoryBeanTest {
@Autowired ApplicationContext context;
@Test public void getFromFactoryBean() {
Object express = context.getBean("express");
System.out.println(((express)express).getExpress());
// result = value in FactoryBeanTest-context.xml
}
@Test public void getFactoryBean() throws Exception {
Object factory = context.getBean("&express"); // get bean itself not a object
if(factory.getClass() == ExpressFactoryBean.class)
System.out.println("True");
}
}
次はテストコードです。
ApplicationContextをDIを使い使用可能にします、
getFromFactoryBeanではcontextファイルを利用してexpressをもってきます。
ここで注目すべきとこは、expressはビンそのものじゃなく
express IDで登録したFactoryBeanを呼び出すところです。
呼び出されたFactoryは、自分自身のメンバ変数にvalueデータを入れ、
そのvalueデータを参照するgetObjectメソッドを利用してオブジェクトを一つ返します。
それでばビンそのものを持って来たい時はどうしましょう。
上記のコードのようにIDの前に「&」を付けでください。
その後、ビンそのものを持ってくるようになります。
ビンを持って来たのかをテストするために
持ってきたビンをgetClass()をしクラスを作成して、
Factoryビンと比べるコードを練ってみました。
結果は
Trueを返します。
FactoryBeanインタフェースを使用する理由は、
getObjectのオブジェクト生成機能にあります。
テストでご覧になったとおり、ビン自体を返すのではなく
FactoryBeanが管理するオブジェクトを返してくれました。
コンストラクタを非公開にしておいて、
staticファクトリメソッドでオブジェクトを生成して返すクラスは、
一般的な方法では、スプリングがビンの形で管理し難い点があります。
しかし、これらの方法を使えば、staticファクトリメソッドを使用するクラスでも
スプリングがビンの管理下に置くことができます。
最後に、これらの過程を簡単に図に作り上げてみました。
댓글 없음:
댓글 쓰기