Spring FactoryBeanの使い方は?
1概要
Spring Beanコンテナーには、通常のBeanとファクトリーBeanの2種類のBeanがあります。 Springは前者を直接使用しますが、後者はフレームワークによって管理されるオブジェクトを自分自身で生成することができます。
簡単に言えば、
org.springframework.beans.factory.FactoryBean
インターフェースを実装することでファクトリBeanを構築できます。
** 2ファクトリービーンズの基本____
__
**
2.1.
FactoryBean
を実装する
最初に
FactoryBean
インターフェースを見てみましょう。
public interface FactoryBean {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
3つの方法について説明しましょう。
-
getObject()
– ファクトリによって生成されたオブジェクトを返します。これは
Springコンテナによって使用されるオブジェクト
**
getObjectType()
– この
FactoryBean
が持つオブジェクトの型を返す
作り出す
**
isSingleton()
– この
FactoryBean
によって生成されたオブジェクトかどうかを示す
シングルトンです
それでは、例
FactoryBean
を実装しましょう。
Tool
型のオブジェクトを生成する
ToolFactory
を実装します。
public class Tool {
private int id;
//standard constructors, getters and setters
}
ToolFactory
自体:
public class ToolFactory implements FactoryBean<Tool> {
private int factoryId;
private int toolId;
@Override
public Tool getObject() throws Exception {
return new Tool(toolId);
}
@Override
public Class<?> getObjectType() {
return Tool.class;
}
@Override
public boolean isSingleton() {
return false;
}
//standard setters and getters
}
ご覧のとおり、
ToolFactory
は
FactoryBean
であり、これは
Tool
オブジェクトを生成できます。
2.2. XMLベースの設定で
FactoryBean
を使用する
それでは、私たちの
ToolFactory
の使い方を見てみましょう。
XMLベースの設定 –
factorybean-spring-ctx.xml
を使用してツールを作成します。
<beans ...>
<bean id="tool" class="com.baeldung.factorybean.ToolFactory">
<property name="factoryId" value="9090"/>
<property name="toolId" value="1"/>
</bean>
</beans>
次に、
Tool
オブジェクトが正しくインジェクトされているかどうかをテストできます。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:factorybean-spring-ctx.xml" })
public class FactoryBeanXmlConfigTest {
@Autowired
private Tool tool;
@Test
public void testConstructWorkerByXml() {
assertThat(tool.getId(), equalTo(1));
}
}
テスト結果は、
factorybean-spring-ctx.xmlで設定したプロパティを使用して、
ToolFactory__によって生成されたツールオブジェクトをインジェクトしたことを示しています。
テスト結果はまた、Springコンテナーが依存性注入のためにそれ自身の代わりに
FactoryBean
によって生成されたオブジェクトを使用することも示しています。
Springコンテナは
FactoryBean
sの
getObject()
メソッドの戻り値をBeanとして使用しますが、
FactoryBean
自体を使用することもできます。
-
FactoryBean
にアクセスするには、単に「
ファクトリBeanとその
factoryId
プロパティを取得してみましょう。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:factorybean-spring-ctx.xml" })
public class FactoryBeanXmlConfigTest {
@Resource(name = "&tool")
private ToolFactory toolFactory;
@Test
public void testConstructWorkerByXml() {
assertThat(toolFactory.getFactoryId(), equalTo(9090));
}
}
2.3. Javaベースの設定で
FactoryBean
を使用する
Javaベースの設定で
FactoryBean
を使用することは、XMLベースの設定では少し異なります。明示的に
FactoryBean
sの
getObject()
メソッドを呼び出す必要があります。
前のサブセクションの例をJavaベースの設定例に変換しましょう。
@Configuration
public class FactoryBeanAppConfig {
@Bean(name = "tool")
public ToolFactory toolFactory() {
ToolFactory factory = new ToolFactory();
factory.setFactoryId(7070);
factory.setToolId(2);
return factory;
}
@Bean
public Tool tool() throws Exception {
return toolFactory().getObject();
}
}
次に、
Tool
オブジェクトが正しくインジェクトされているかどうかをテストします。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = FactoryBeanAppConfig.class)
public class FactoryBeanJavaConfigTest {
@Autowired
private Tool tool;
@Resource(name = "&tool")
private ToolFactory toolFactory;
@Test
public void testConstructWorkerByJava() {
assertThat(tool.getId(), equalTo(2));
assertThat(toolFactory.getFactoryId(), equalTo(7070));
}
}
テスト結果は、以前のXMLベースの構成テストと同様の効果を示しています。
3初期化する方法
プロパティチェックのように、
FactoryBean
が設定された後、
getObject()
メソッドが呼び出される前に、いくつかの操作を実行する必要がある場合があります。
これを実現するには、
InitializingBean
インターフェースを実装するか、または
@ PostConstruct
アノテーションを使用します。
これら2つの解決策を使用することに関する詳細は別の記事で紹介されました:。
4
AbstractFactoryBean
Springは
AbstractFactoryBean
を
FactoryBean
実装のためのシンプルなテンプレートスーパークラスとして提供しています。この基本クラスを使用すると、シングルトンオブジェクトまたはプロトタイプオブジェクトを作成するファクトリBeanをより便利に実装できます。
シングルトン型とプロトタイプ型の両方に
AbstractFactoryBean
を使用する方法を示すために
SingleToolFactory
と
NonSingleToolFactory
を実装しましょう。
public class SingleToolFactory extends AbstractFactoryBean<Tool> {
private int factoryId;
private int toolId;
@Override
public Class<?> getObjectType() {
return Tool.class;
}
@Override
protected Tool createInstance() throws Exception {
return new Tool(toolId);
}
//standard setters and getters
}
そして今、非シングルトン実装:
public class NonSingleToolFactory extends AbstractFactoryBean<Tool> {
private int factoryId;
private int toolId;
public NonSingleToolFactory() {
setSingleton(false);
}
@Override
public Class<?> getObjectType() {
return Tool.class;
}
@Override
protected Tool createInstance() throws Exception {
return new Tool(toolId);
}
//standard setters and getters
}
また、これらのファクトリBeanのXML設定は以下のとおりです。
<beans ...>
<bean id="singleTool" class="com.baeldung.factorybean.SingleToolFactory">
<property name="factoryId" value="3001"/>
<property name="toolId" value="1"/>
</bean>
<bean id="nonSingleTool" class="com.baeldung.factorybean.NonSingleToolFactory">
<property name="factoryId" value="3002"/>
<property name="toolId" value="2"/>
</bean>
</beans>
期待どおりに
Worker
オブジェクトのプロパティがインジェクトされているかどうかをテストできます。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:factorybean-abstract-spring-ctx.xml" })
public class AbstractFactoryBeanTest {
@Resource(name = "singleTool")
private Tool tool1;
@Resource(name = "singleTool")
private Tool tool2;
@Resource(name = "nonSingleTool")
private Tool tool3;
@Resource(name = "nonSingleTool")
private Tool tool4;
@Test
public void testSingleToolFactory() {
assertThat(tool1.getId(), equalTo(1));
assertTrue(tool1 == tool2);
}
@Test
public void testNonSingleToolFactory() {
assertThat(tool3.getId(), equalTo(2));
assertThat(tool4.getId(), equalTo(2));
assertTrue(tool3 != tool4);
}
}
テストからわかるように、
SingleToolFactory
はシングルトンオブジェクトを生成し、
NonSingleToolFactory
はプロトタイプオブジェクトを生成します。
AbstractFactory
では、シングルトンプロパティのデフォルト値が
true
であるため、
SingleToolFactory
にシングルトンプロパティを設定する必要はありません。
5結論
FactoryBean
を使用すると、複雑な構築ロジックをカプセル化したり、高度に設定可能なオブジェクトをSpringで簡単に設定したりすることができます。
そのため、この記事では、
FactoryBean
の実装方法、XMLベースの構成とJavaベースの構成の両方での使用方法、および
FactoryBean
や
AbstractFactoryBean
の初期化など、その他のいくつかの
FactoryBean
の側面について紹介しました。
いつものように、このhttps://github.com/eugenp/tutorials/tree/master/spring-core/src/main/java/com/baeldung/factorybean[GitHubプロジェクト]の完全なソース