知識庫 / Spring RSS 訂閱

通過工廠方法創建 Spring Bean

Spring
HongKong
11
01:00 PM · Dec 06 ,2025

1. 簡介

工廠方法可以作為一種有用的技術,用於將複雜的創建邏輯隱藏在一個方法調用中。

雖然我們通常使用構造函數或字段注入在 Spring 中創建 Bean,我們也可以使用工廠方法創建 Spring Bean

在本教程中,我們將深入研究使用實例工廠方法和靜態工廠方法創建 Spring Bean。

2. 實例工廠方法

標準實現實例工廠方法模式是創建一個方法,該方法返回所需的 Bean。

此外,我們可以配置 Spring 以使用或不使用參數創建我們的所需 Bean

2.1. 無參數

我們可以創建一個 Foo 類來表示我們的 Bean 被創建:

public class Foo {}

然後,我們創建一個名為 InstanceFooFactory 的類,其中包含一個工廠方法,createInstance,該方法創建我們的 Foo Bean:

public class InstanceFooFactory {

    public Foo createInstance() {
        return new Foo();
    }
}

之後,我們配置 Spring:

  1. 創建一個 Bean,用於我們的工廠類(InstanceFooFactory
  2. 使用 factory-bean 屬性引用我們的工廠 Bean
  3. 使用 factory-method 屬性引用我們的工廠方法(createInstance
將此應用到 Spring XML 配置中,我們最終得到:
<beans ...>

    <bean id="instanceFooFactory"
      class="com.baeldung.factorymethod.InstanceFooFactory" />

    <bean id="foo"
      factory-bean="instanceFooFactory"
      factory-method="createInstance" />

</beans>

最後,我們自動注入所需的 Foo Bean。Spring 將使用我們的 createInstance 工廠方法創建該 Bean:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/factorymethod/instance-config.xml")
public class InstanceFooFactoryIntegrationTest {

    @Autowired
    private Foo foo;
    
    @Test
    public void givenValidInstanceFactoryConfig_whenCreateFooInstance_thenInstanceIsNotNull() {
        assertNotNull(foo);
    }
}

2.2. 使用參數

我們還可以使用 Spring 配置中的 constructor-arg 元素,向我們的實例工廠方法提供參數。

首先,我們創建一個類,Bar,它使用了參數。

public class Bar {

    private String name;

    public Bar(String name) {
        this.name = name;
    }

    // ...getters & setters
}

接下來,我們創建一個實例工廠類 InstanceBarFactory,該類包含一個工廠方法,它接受一個參數並返回一個 Bar Bean:

public class InstanceBarFactory {

    public Bar createInstance(String name) {
        return new Bar(name);
    }
}

最後,我們向我們的 Bar Bean 定義中添加了一個 constructor-arg 元素:

<beans ...>

    <bean id="instanceBarFactory"
      class="com.baeldung.factorymethod.InstanceBarFactory" />

    <bean id="bar"
      factory-bean="instanceBarFactory"
      factory-method="createInstance">
        <constructor-arg value="someName" />
    </bean>

</beans>

我們可以以同樣的方式自動注入我們的 Bar Bean,就像我們為 Foo Bean 做的的那樣:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/factorymethod/instance-bar-config.xml")
public class InstanceBarFactoryIntegrationTest {

    @Autowired
    private Bar instance;
    
    @Test
    public void givenValidInstanceFactoryConfig_whenCreateInstance_thenNameIsCorrect() {
        assertNotNull(instance);
        assertEquals("someName", instance.getName());
    }
}

3. 靜態工廠方法

我們還可以配置 Spring 使用靜態方法作為工廠方法。

雖然實例工廠方法應該首選,但這種技術在我們需要使用現有的、遺留的靜態方法來生成所需的 Bean 時非常有用。例如,如果一個工廠方法返回的是單例,我們可以配置 Spring 使用這個單例工廠方法。

類似於實例工廠方法,我們可以配置靜態方法,並可以指定參數。

3.1. 無參數

使用我們的 Foo 類作為所需 Bean,我們可以創建一個類, SingletonFooFactory,其中包含一個 createInstance 工廠方法,該方法返回 Foo 的單例實例:

public class SingletonFooFactory {

    private static final Foo INSTANCE = new Foo();
    
    public static Foo createInstance() {
        return INSTANCE;
    }
}

本次,我們只需要創建 одном bean. 這個 Bean 只需要兩個屬性:

  1. class – 聲明我們的工廠類 (SingletonFooFactory)
  2. factory-method – 聲明靜態工廠方法 (createInstance)

將此應用到我們的 Spring XML 配置,我們得到:

<beans ...>

    <bean id="foo"
      class="com.baeldung.factorymethod.SingletonFooFactory"
      factory-method="createInstance" />

</beans>

最後,我們使用與之前相同的方式自動注入 Foo Bean:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/factorymethod/static-foo-config.xml")
public class SingletonFooFactoryIntegrationTest {

    @Autowired
    private Foo singleton;
    
    @Test
    public void givenValidStaticFactoryConfig_whenCreateInstance_thenInstanceIsNotNull() {
        assertNotNull(singleton);
    }
}

3.2. 使用參數

雖然我們應該儘可能避免更改靜態對象的狀態——比如我們的單例,但我們仍然可以向我們的靜態工廠方法傳遞參數。

要做到這一點,我們創建一個新的工廠方法,該方法接受我們想要的參數:

public class SingletonBarFactory {

    private static final Bar INSTANCE = new Bar("unnamed");
    
    public static Bar createInstance(String name) {
        INSTANCE.setName(name);
        return INSTANCE;
    }
}

之後,我們使用 constructor-arg 元素將所需的參數傳遞給 Spring:

<beans ...>

    <bean id="bar"
      class="com.baeldung.factorymethod.SingletonBarFactory"
      factory-method="createInstance">
        <constructor-arg value="someName" />
    </bean>

</beans>

最後,我們使用與之前相同的方式自動注入<em>Bar</em> Bean:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/factorymethod/static-bar-config.xml")
public class SingletonBarFactoryIntegrationTest {

    @Autowired
    private Bar instance;
    
    @Test
    public void givenValidStaticFactoryConfig_whenCreateInstance_thenNameIsCorrect() {
        assertNotNull(instance);
        assertEquals("someName", instance.getName());
    }
}

4. 結論

在本文中,我們探討了如何配置 Spring 使用實例方法和靜態工廠方法,無論是否包含參數。

雖然通過構造函數和字段注入創建 Bean 更加常見,但工廠方法在處理複雜的創建步驟和遺留代碼時非常有用。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.