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プロジェクト]の完全なソース