Bean的实例化方式
大约 3 分钟
Spring为Bean提供了多种实例化⽅式,让bean对象的创建更加灵活,通常包括4种⽅式。
- 通过构造⽅法实例化
- 通过简单⼯⼚模式实例化
- 通过factory-bean实例化
- 通过FactoryBean接⼝实例化
不同于 依赖注入,实例化方式是 Spring 获取这个bean对象的方式,可以通过调用构造方法获取bean对象(同时可以注入依赖, 即构造注入),也支持通过工厂获取bean对象。Spring 获取bean对象后,才能放入容器内进行管理或者set注入。
<bean>的类型并不是由class属性决定的,而是由实例化方式的结果决定。
通过构造方法实例化
默认情况下,会调⽤Bean的⽆参数构造⽅法。配置构造注入时即调用有参数构造方法并完成注入。
使用构造方法实例化,class 属性即为bean的类型。
通过简单工厂模式实例化
<bean id="vipBean" class="com.powernode.spring6.bean.VipFactory" factory-method="get"/>
<!--
class 是简单工厂类
factory-method 必须是这个工厂类的**静态方法**
-->如何传参:
<bean id="user-simple-factory" class="com.guitar.bean.UserSimpleFactory" factory-method="getUser">
<constructor-arg name="tag" value="constructor-arg"></constructor-arg>
</bean>- 像构造注入般,使用
<constructor-arg>即可。 - bean 的类型取决于工厂方法的返回值类型。
过程猜测:
- 调用指定的静态方法,并传入
<constructor-arg>指定的参数 - 执行结果作为 bean对象,管理在容器内。
- 解析
<property>完成set注入
通过factory-bean实例化
底层:使用工厂方法模式进行实例化。
区别于“通过简单工厂模式实例化”使用静态方法,这里是通过执行实例方法完成实例化。
<!--具体工厂实例-->
<bean id="orderFactory" class="com.powernode.spring6.bean.OrderFactory"/>
<!--factory-bean 引用 具体工厂bean,调用 factory-method 指定的方法完成实例化-->
<bean id="orderBean" factory-bean="orderFactory" factory-method="get"/>- factory-method 不能是静态方法,必须是实例方法。
- 把执行结果作为bean,传参、set注入同上。
通过FactoryBean接口实例化
Spring 为工厂模式提供了特殊的支持,如果一个工厂实现了 org.springframework.beans.factory.FactoryBean 接口,则 bean 配置可以极大地简化。
实现类案例:
public class PersonFactoryBean implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person();
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
// true表示单例
// false表示原型
return true;
}
}配置信息:
<bean id="person" class="com.powernode.spring6.bean.PersonFactoryBean"/>- Spring 检测到这个 class 实现了 FactoryBean 接口后,会将其视为一个工厂bean,调用
getObject(),返回值作为 bean对象。
过程猜测:
- 解析 class,知道这个 class 是个工厂bean
- 解析
<constructor-arg>,调用 工厂bean 的构造方法完成工厂bean 的实例化,同时纳入特殊管理。 - 解析
<property>对 工厂bean 完成set注入。 - 调用工厂bean 的
getObject(),将返回值作为名为 id 的 bean对象。
- 构造注入、set注入都是对工厂bean的,在这个工厂bean内提供属性,从而简介控制对产品bean的生产。
FactoryBean 在 Spring中是⼀个接⼝。被称为**“⼯⼚Bean”**。
“⼯⼚Bean”是⼀种特殊的Bean。所有的“⼯⼚Bean”都是⽤来协助Spring框架来创建其他Bean对象的。
Spring 的两类 Bean:
- 普通bean。
- 工厂bean(FactoryBean)。多一步调用
getObject()作为指定 id 的 bean。
BeanFactory和FactoryBean的区别
BeanFactory:Spring IoC容器的顶级对象,BeanFactory被翻译为**“Bean⼯⼚”,在Spring的IoC容器中,“Bean⼯⼚”负责创建Bean对象**。是一个工厂。
FactoryBean:是⼀个能够辅助Spring实例化其它Bean对象的⼀个Bean。是一个 Bean。
使用FactoryBean实现日期的生产
定义 DateFactoryBean:
public class DateFactoryBean implements FactoryBean<Date> {
// 定义属性接收⽇期字符串
private String date;
// ...
}使用 DateFactoryBean 生产 Date:
<!-- dateBean 的类型是 Date-->
<bean id="dateBean" class="com.powernode.spring6.bean.DateFactoryBean">
<!--构造注入,给 DateFactoryBean 的属性传值-->
<constructor-arg name="date" value="1999-10-11"/>
</bean>
<bean id="studentBean" class="com.powernode.spring6.bean.Student">
<property name="birth" ref="dateBean"/>
</bean>