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