spring源碼——BeanFactory和FactoryBean的區別

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
發佈了24 篇原創文章 · 獲贊 11 · 訪問量 5518
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章