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