BeanFactory 和 FactoryBean的区别
BeanFactory
这个其实是所有 Spring Bean 的容器根接口,给 Spring 的容器定义一套规范,给 IOC 容器提供了一套完整的规范,比如我们常用到的 getBean 方法等
The root interface for accessing a Spring bean container. This is the basic client view of a bean container;
定义方法:
- getBean(String name): Spring 容器中获取对应 Bean 对象的方法,如存在,则返回该对象
- containsBean(String name):Spring 容器中是否存在该对象
- isSingleton(String name):通过 beanName 是否为单例对象
- isPrototype(String name):判断 bean 对象是否为多例对象
- isTypeMatch(String name, ResolvableType typeToMatch):判断 name 值获取出来的 bean 与 typeToMath 是否匹配
- getType(String name):获取 Bean 的 Class 类型
- getAliases(String name):获取 name 所对应的所有的别名
FactoryBean
该类是 SpringIOC 容器是创建 Bean 的一种形式,这种方式创建 Bean 会有加成方式,融合了简单的工厂设计模式于装饰器模式
一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
Spring 为此提供了一个 org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。FactoryBean 接口对于 Spring 框架来说占用重要的地位,Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring3.0 开始,FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式
以 Bean 结尾,表示它是一个 Bean,不同于普通 Bean 的是:它是实现了 FactoryBean<T> 接口的 Bean,根据该 Bean 的 ID 从 BeanFactory 中获取的实际上是 FactoryBean 的 getObject()返回的对象,而不是 FactoryBean 本身,如果要获取 FactoryBean 对象,请在 id 前面加一个&符号来获取。
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.valueOf(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return false;
}
public String getCarInfo() {
return this.carInfo;
}
// 接受逗号分割符设置属性信息
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}
有了这个 CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 CarBean 了:
<bean d="car"class="com.baobaotao.factorybean.CarFactoryBean" P:carInfo="法拉利,400,2000000"/>
当调用 getBean(“car”)时,Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时 Spring 容器就调用接口方法 CarFactoryBean#getObject()方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName)方法时在 beanName 前显示的加上"&“前缀:如 getBean(”&car");
区别
- BeanFactory:负责生产和管理 Bean 的一个工厂接口,提供一个 Spring Ioc 容器规范,
- FactoryBean: 一种 Bean 创建的一种方式,对 Bean 的一种扩展。对于复杂的 Bean 对象初始化创建使用其可封装对象的创建细节。
原文: