BeanFactory和FactoryBean的区别
BeanFactory
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,
具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext等,用来生产bean,通过getBean方法能够得到一个bean;此处我们重点分析FactoryBean。
FactoryBean
FactoryBean是spring当中的一个特殊的bean,它是一个接口,实现了FactoryBean的bean能够再创建一个bean,如果你的类实现了FactoryBean,那么spring容器当中存在两个对象,一个是通过getObject()返回的对象,还有一个为当前对象,getObject得到的对象存的是当前类@Component(“名字”)指定的名字,当前对象是“&”+指定的名字。
使用场景: 当一个类,他的依赖关系很复杂的时候,而我们想对外提供简单的一种关系,让外部去配置出来的时候,可以使用FactoryBean,经典的场景如mybatis中的SqlSessionFactoryBean。
FactoryBean:
//工厂Bean,用于产生其他对象
//可以让我们自定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
//获取容器管理的对象实例
//返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器的单例对象缓存池中Map
@Nullable
T getObject() throws Exception;
//获取Bean工厂创建的对象的类型
@Nullable
Class<?> getObjectType();
//Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例
//对象,每次请求都返回同一个实例对象
default boolean isSingleton() {
return true;
}
}
案例
Company :
public class Company {
private String name;
private String address;
private int scale;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getScale() {
return scale;
}
public void setScale(int scale) {
this.scale = scale;
}
@Override
public String toString() {
return "Company{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
", scale=" + scale +
'}';
}
}
CompanyFactoryBean:
public class CompanyFactoryBean implements FactoryBean<Company> {
private String companyInfo; // 公司名称,地址,规模
public void setCompanyInfo(String companyInfo) {
this.companyInfo = companyInfo;
}
@Override
public Company getObject() throws Exception {
// 模拟创建复杂对象Company
Company company = new Company();
String[] strings = companyInfo.split(",");
company.setName(strings[0]);
company.setAddress(strings[1]);
company.setScale(Integer.parseInt(strings[2]));
return company;
}
@Override
public Class<?> getObjectType() {
return Company.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
注入spring,配置xml:
<bean id="companyBean" class="com.lagou.edu.factory.CompanyFactoryBean">
<property name="companyInfo" value="拉勾,中关村,500"/>
</bean>
测试类:
public static void main(String[] args) {
Object companyBean = applicationContext.getBean("companyBean");
System.out.println("bean:" + companyBean);
}
运行结果
bean:Company{name='拉勾', address='中关村', scale=500}
如果想获取FactoryBean,需要在id之前添加“&”
测试类:
public static void main(String[] args) {
Object companyBean = applicationContext.getBean("&companyBean");
System.out.println("bean:" + companyBean);
}
运行结果
bean:com.lagou.edu.factory.CompanyFactoryBean@53f6fd09