前面大概解讀了beanFactory和factoryBean的源碼註釋,但是可能很多人還是一頭霧水,首先是筆者的英文水平有期,其次,筆者對整個框架的理解不是很到位,所以一些翻譯並不能真正表達框架設計者的意圖。但是通過對兩者對比,相信我們會對這兩個接口有更深刻的理解。
BeanFactory
beanFactory是ioc容器的接口,是一個工廠類,負責創建,管理bean,spring 中所有bean都是交由beanFactory來管理。beanfactory有好多派生類如applicationContext,DefaultListableBeanFactory,xmlBeanFactory.具體beanfactory內部api理解可查看以前博客
FactoryBean
beanFactory比較好理解,下面我們着重說一下FactoryBean.
factoryBean是一個bean,是一個特殊的bean,他是一個能生產和修飾對象生成的工廠bean,他和普通bean的區別在於返回的不是一個特定類的實例,而是他的getobject方法返回的對象。
正常情況下,spring利用反射通過bean的class屬性實例化bean,但是當bean的實例化過程很複雜的時候,此時通過配置實例化bean就很繁瑣,所以spring提供了factoryBean接口,幫助我們自定義複雜的實例化過程。
factoryBean接口在spring中佔有重要地位,spring本身就有70多個bean實現這個接口。它隱藏了複雜bean 的實現細節,爲上層應用調用提供便利。
當bean 的class屬性是一個factorybean時,調用getbean方法,返回的是factorybean內部getObject方法返回的對象,而不是factoryBean本身,相當於factoryBean的getObject方法代理了getBean方法。
示例如下:
如果想返回一個personbean,
public class Person {
private String name;
private int age;
private int sex;
public Person(String name, int age, int sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
如果用傳統方式配置,person的每個屬性配置一個property元素標籤,用factorybean的方式
public class PersonFactoryBean implements FactoryBean<Person> {
private String personInfo;
@Override
public Person getObject() throws Exception {
Person person=new Person();
String[] personInfos=personInfo.split(",");
person.setName(personInfos[0]);
person.setAge(personInfos[1]);
person.setSex(personInfos[2]);
return person;
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
public String getPersonInfo() {
return personInfo;
}
public void setPersonInfo(String personInfo) {
this.personInfo = personInfo;
}
}
然後可以在配置文件中如下配置
<bean id="Person"class="cn.newhope.de.entity.PersonFactoryBean" P:personInfo ="李明,20,1"/>
當調用getbean(“person”)方法時,spring 發現這是一個factoryBean,然後會調用factoryBean的getObject方法返回對象。如果希望返回factoryBean 的實例,在前面加上&即可,即getbean(“&person”)。
至此,基本描述清楚factoryBean的特殊之處,剛開始看兩個接口源碼註釋筆者很迷茫,很多英文具體含義都是似懂非懂,也是通過看網上的其他優秀博客,再回頭看英文註釋,纔會恍然,原來如此,爲此,建議結合網上的優秀案例和英文註釋學習,而不是矇頭看源碼。
最後,附上我以前翻譯的源碼註釋:
beanFactory詳解
factoryBean詳解
感謝閱讀,如有錯誤之處,請不吝指正。