spring---FactoryBean与BeanFactory的区别
1.BeanFactory
BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,
XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
BeanFactory源码
-
package org.springframework.beans.factory;
-
import org.springframework.beans.BeansException;
-
public interface BeanFactory {
-
String FACTORY_BEAN_PREFIX = "&";
-
Object getBean(String name) throws BeansException;
-
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
-
<T> T getBean(Class<T> requiredType) throws BeansException;
-
Object getBean(String name, Object... args) throws BeansException;
-
boolean containsBean(String name);
-
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
-
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
-
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
-
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
-
String[] getAliases(String name);
-
}
2.FactoryBean
FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。
FactoryBean源码
-
package org.springframework.beans.factory;
-
public interface FactoryBean<T> {
-
T getObject() throws Exception;
-
Class<?> getObjectType();
-
boolean isSingleton();
-
}
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:tx="http://www.springframework.org/schema/tx"
-
xsi:schemaLocation="http://www.springframework.org/schema/beans
-
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-
http://www.springframework.org/schema/context
-
http://www.springframework.org/schema/context/spring-context-3.0.xsd
-
http://www.springframework.org/schema/aop
-
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
-
http://www.springframework.org/schema/tx
-
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
-
<bean id="student" class="com.spring.bean.Student">
-
<property name="name" value="zhangsan" />
-
</bean>
-
-
<bean id="school" class="com.spring.bean.School">
-
</bean>
-
-
<bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo">
-
<property name="type" value="student" />
-
</bean>
-
</beans>
FactoryBean的实现类
-
import org.springframework.beans.factory.FactoryBean;
-
-
/**
-
* @author 作者 wangbiao
-
* @date 创建时间:2016年11月14日 上午11:19:31
-
* @parameter
-
* @return
-
*/
-
public class FactoryBeanPojo implements FactoryBean{
-
private String type;
-
-
-
public Object getObject() throws Exception {
-
if("student".equals(type)){
-
return new Student();
-
}else{
-
return new School();
-
}
-
-
}
-
-
-
public Class getObjectType() {
-
return School.class;
-
}
-
-
-
public boolean isSingleton() {
-
return true;
-
}
-
-
public String getType() {
-
return type;
-
}
-
-
public void setType(String type) {
-
this.type = type;
-
}
-
-
}
普通的bean
-
/**
-
* @author 作者 wangbiao
-
* @date 创建时间:2016年11月14日 上午11:13:18
-
* @parameter
-
* @return
-
*/
-
public class School {
-
private String schoolName;
-
private String address;
-
private int studentNumber;
-
public String getSchoolName() {
-
return schoolName;
-
}
-
public void setSchoolName(String schoolName) {
-
this.schoolName = schoolName;
-
}
-
public String getAddress() {
-
return address;
-
}
-
public void setAddress(String address) {
-
this.address = address;
-
}
-
public int getStudentNumber() {
-
return studentNumber;
-
}
-
public void setStudentNumber(int studentNumber) {
-
this.studentNumber = studentNumber;
-
}
-
-
public String toString() {
-
return "School [schoolName=" + schoolName + ", address=" + address
-
+ ", studentNumber=" + studentNumber + "]";
-
}
-
}
测试类
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
import com.spring.bean.FactoryBeanPojo;
-
-
/**
-
* @author 作者 wangbiao
-
* @date 创建时间:2016年11月14日 上午11:11:35
-
* @parameter
-
* @return
-
*/
-
public class FactoryBeanTest {
-
public static void main(String[] args){
-
String url = "com/spring/config/BeanConfig.xml";
-
ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
-
Object school= cpxa.getBean("factoryBeanPojo");
-
FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");
-
System.out.println(school.getClass().getName());
-
System.out.println(factoryBeanPojo.getClass().getName());
-
}
-
}
-
十一月 16, 2016 10:28:24 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
-
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e8ee5c0: startup date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy
-
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
-
INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml]
-
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
-
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy
-
com.spring.bean.Student
-
com.spring.bean.FactoryBeanPojo
从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。
3.BeanFactory和FactoryBean的区别
BeanFactory和FactoryBean其实没有什么比较性的,只是两者的名称特别接近,所以有时候会拿出来比较一番,BeanFactory是提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范,FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类,要想深入准确的理解FactoryBean,只有去读读Spring源码了。