0%

Spring学习笔记 - Spring FactoryBean

简述

org.springframework.beans.factory.FactoryBean<T>Spring容器提供的一种可以扩展容器对象实例化逻辑的接口。FactoryBean,其主语是Ben,定于为Factory,也就是说,它本身与其他注册到容器中的对象一样,只是一个Bean而已,只不过这种类型的Bean本身就是生产对象的工厂。

接口定义

它的接口定义如下

1
2
3
4
5
6
7
8
9
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}

getObject()方法会返回该FactoryBean“生产”的对象实例,我们需要实现该方法以给出自己的对象实例化逻辑;getObjectType()方法仅返回getObject()方法所返回的对象的类型,如果预先无法确定,则返回null;isSingleton()方法返回结果用于表明,工厂方法(getObject())所“生产”的对象是否要以singleton形式存在于容器中。如果以singleton形式存在,则返回true,否则返回false;

使用场景

FactoryBean的一般使用场景是,当我们需要实例化一个比较复杂的Bean时,我们可以通过实现FactoryBean来定制Bean的实例化过程。

在IOC容器中,通过getBean(BeanName)方法获取Bean时,如果该Bean实现了FactoryBean接口,则获取到该Bean的实例为getObjet()方法返回的结果,并不是FactoryBean的实现类对象。

使用示例

我们实现一个FactoryBean示例,我们将实现一个ToolFactory,它将产生Tool类型的实例对象。

1
2
3
4
5
6
public class Tool {
 
    private int id;
 
    // standard constructors, getters and setters
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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的实现注册到IOC容器中),有以下两种方式:

  • XML

    1
    2
    3
    4
    5
    6
    7
    <beans ...>
     
        <bean id="tool" class="com.baeldung.factorybean.ToolFactory">
            <property name="factoryId" value="9090"/>
            <property name="toolId" value="1"/>
        </bean>
    </beans>
  • Java编码

    与XML不同的是,我们需要显示的调用getObject()方法来生成实例对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @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实例对象即可

1
2
3
4
5
6
7
8
9
public class FactoryBeanTest {
@Autowired
private Tool tool;

@Test
public void test() {
assertThat(tool.getId(), equalTo(1));
}
}