1. 引入
在之前静态工厂和实例工厂中,我们想要获取一个bean实例对象,需要先配置工厂bean,之后指定调用方法名,才能获取到目标对象。
例如静态工厂如下:
<bean id="clientService" class="org.kkk.spring.ioc.ClientService" factory-method="getInstance" />
实例工厂如下:
<!--1. 配置工厂类的组件信息 -->
<bean id="clientServiceFactory" class="org.kkk.spring.ioc.ClientServiceFactory" />
<!--2. 通过指定非静态工厂对象和方法名 来配置生成的ioc信息 -->
<bean id="clientService" factory-bean="clientServiceFactory" factory-method="getInstance" />
整个过程还是略显麻烦,那么有没有什么更快捷的方法。factorybean就是答案。
2. FactoryBean
2.1 FactoryBean简介
FactoryBean 接口是Spring IoC容器实例化逻辑的可插拔性点。用于配置复杂的Bean对象,可以将创建过程存储在FactoryBean 的getObject方法。换句话说,只要我们创建一个工厂类实现FactoryBean接口,那么IOC可以自动创建工厂实例并执行getObject方法,我们可以直接获得目标对象。
FactoryBean 接口提供三种方法:
-
T getObject()
:返回此工厂创建的对象的实例。该返回值会被存储到IoC容器。
-
boolean isSingleton()
:如果此 FactoryBean 返回单例,则返回 true ,否则返回 false 。此方法的默认实现返回 true 。
-
Class<?> getObjectType()
:返回 getObject() 方法返回的对象类型,如果事先不知道类型,则返回 null 。
2.2 FactoryBean使用
-
创建工厂类
举例如下:
public class MyFactoryBean implements FactoryBean<MyMachine> {
private String machineName;
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
@Override
public MyMachine getObject() throws Exception {
// 方法内部模拟创建、设置一个对象的复杂过程
MyMachine myMachine = new MyMachine();
myMachine.setMachineName(this.machineName);
return myMachine;
}
@Override
public Class<?> getObjectType() {
// 返回要生产的对象的类型
return MyMachine.class;
}
}
- XML配置文件
<bean id="MyMachine" class="org.kkk.ioc.MyFactoryBean">
<property name="machineName" value="iceCreamMachine"/>
</bean>
注意:
- bean标签中class属性指定的是MyFactoryBean,但是将来从这里获取的bean是MyMachine对象
- 工厂类中的property标签是给MyFactoryBean的对象属性赋值,而不是给myMachine属性赋值
- 此时,如果想要获取FactoryBean对象, 直接在id前添加&符号即可,例如此时为&MyMachine