BeanFactory和FactoryBean的区别

转自:http://blog.csdn.net/wangbiao007/article/details/53183764 

1.BeanFactory

             BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,

XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。

 BeanFactory源码             

  1. package org.springframework.beans.factory;    
  2. import org.springframework.beans.BeansException;    
  3. public interface BeanFactory {    
  4.     String FACTORY_BEAN_PREFIX = "&";    
  5.     Object getBean(String name) throws BeansException;    
  6.     <T> T getBean(String name, Class<T> requiredType) throws BeansException;    
  7.     <T> T getBean(Class<T> requiredType) throws BeansException;    
  8.     Object getBean(String name, Object... args) throws BeansException;    
  9.     boolean containsBean(String name);    
  10.     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;    
  11.     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;    
  12.     boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;    
  13.     Class<?> getType(String name) throws NoSuchBeanDefinitionException;    
  14.     String[] getAliases(String name);    
  15. }    

        2.FactoryBean

             FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

 FactoryBean源码

 
  1. package org.springframework.beans.factory;    
  2. public interface FactoryBean<T> {    
  3.     T getObject() throws Exception;    
  4.     Class<?> getObjectType();    
  5.     boolean isSingleton();    
  6. }   

下面是一个应用FactoryBean的例子

 
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.              xmlns:context="http://www.springframework.org/schema/context"  
  4.              xmlns:aop="http://www.springframework.org/schema/aop"  
  5.              xmlns:tx="http://www.springframework.org/schema/tx"  
  6.              xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.                      http://www.springframework.org/schema/context  
  9.                      http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  10.                      http://www.springframework.org/schema/aop  
  11.                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
  12.                      http://www.springframework.org/schema/tx  
  13.                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">  
  14.       
  15.  <bean id="student" class="com.spring.bean.Student">    
  16.   <property name="name" value="zhangsan" />    
  17.  </bean>    
  18.    
  19.  <bean id="school" class="com.spring.bean.School">    
  20.  </bean>   
  21.    
  22.  <bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo">    
  23.     <property name="type" value="student" />  
  24.  </bean>   
  25. </beans>    

FactoryBean的实现类

 
  1. import org.springframework.beans.factory.FactoryBean;  
  2.   
  3. /**  
  4.  * @author  作者 wangbiao 
  5.  * @date 创建时间:2016年11月14日 上午11:19:31  
  6.  * @parameter  
  7.  * @return  
  8.  */  
  9. public class FactoryBeanPojo implements FactoryBean{  
  10.     private String type;  
  11.   
  12.     @Override  
  13.     public Object getObject() throws Exception {  
  14.         if("student".equals(type)){  
  15.             return new Student();             
  16.         }else{  
  17.             return new School();  
  18.         }  
  19.           
  20.     }  
  21.   
  22.     @Override  
  23.     public Class getObjectType() {  
  24.         return School.class;  
  25.     }  
  26.   
  27.     @Override  
  28.     public boolean isSingleton() {  
  29.         return true;  
  30.     }  
  31.   
  32.     public String getType() {  
  33.         return type;  
  34.     }  
  35.   
  36.     public void setType(String type) {  
  37.         this.type = type;  
  38.     }  
  39.       
  40. }  

普通的bean

 
  1. /**  
  2.  * @author  作者 wangbiao 
  3.  * @date 创建时间:2016年11月14日 上午11:13:18  
  4.  * @parameter  
  5.  * @return  
  6.  */  
  7. public class School {  
  8.     private String schoolName;  
  9.     private String address;  
  10.     private int studentNumber;  
  11.     public String getSchoolName() {  
  12.         return schoolName;  
  13.     }  
  14.     public void setSchoolName(String schoolName) {  
  15.         this.schoolName = schoolName;  
  16.     }  
  17.     public String getAddress() {  
  18.         return address;  
  19.     }  
  20.     public void setAddress(String address) {  
  21.         this.address = address;  
  22.     }  
  23.     public int getStudentNumber() {  
  24.         return studentNumber;  
  25.     }  
  26.     public void setStudentNumber(int studentNumber) {  
  27.         this.studentNumber = studentNumber;  
  28.     }  
  29.     @Override  
  30.     public String toString() {  
  31.         return "School [schoolName=" + schoolName + ", address=" + address  
  32.                 + ", studentNumber=" + studentNumber + "]";  
  33.     }  
  34. }  

测试类

 
  1. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  2.   
  3. import com.spring.bean.FactoryBeanPojo;  
  4.   
  5. /**  
  6.  * @author  作者 wangbiao 
  7.  * @date 创建时间:2016年11月14日 上午11:11:35  
  8.  * @parameter  
  9.  * @return  
  10.  */  
  11. public class FactoryBeanTest {  
  12.     public static void main(String[] args){  
  13.         String url = "com/spring/config/BeanConfig.xml";  
  14.         ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);  
  15.         Object school=  cpxa.getBean("factoryBeanPojo");  
  16.         FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");  
  17.         System.out.println(school.getClass().getName());  
  18.         System.out.println(factoryBeanPojo.getClass().getName());  
  19.     }  
  20. }  

输出的结果:

 
  1. 十一月 16, 2016 10:28:24 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh  
  2. INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e8ee5c0: startup date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy  
  3. 十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions  
  4. INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml]  
  5. 十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons  
  6. INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy  
  7. com.spring.bean.Student  
  8. 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源码了。

原文地址:https://www.cnblogs.com/SimonHu1993/p/7695797.html