前面大概解读了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详解
感谢阅读,如有错误之处,请不吝指正。