Spring 框架学习:BeanFactory 和 FactoryBean

 

1. BeanFactory

  BeanFactory定义了IoC容器的最基本形式,也就是 Spring IoC 所遵守的最底层和最基本的编程规范。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。ApplicationContext是BeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。

  简而言之,BeanFactory提供了配制框架及基本功能,而ApplicationContext则增加了更多支持企业核心内容的功能。ApplicationContext完全由BeanFactory扩展而来,因而BeanFactory所具备的能力和行为也适用于ApplicationContext
  org.springframework.beans.factory.BeanFactory是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。在Spring中,BeanFactory是IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖Spring为我们提供了许多易用的BeanFactory实现,如 DefaultListableBeanFactory、XmlBeanFactory,XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
 
2. FactoryBean
  工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。在Spring框架内部,有很多地方有FactoryBean的实现类,它们在很多应用如(Spring的AOP、ORM、事务管理)及与其它第三框架(ehCache)集成时都有体现。

  一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

在该接口中还定义了以下3 个方法:

T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;

boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了getBean() 方法。

下面简单分析FactoryBean的用法。 

 

 1 public class SimpleFactoryBean implements FactoryBean {  
 2         private boolean flag;  
 3       
 4         public Object getObject() throws Exception {  
 5             if (flag) {  
 6                 return new Date();  
 7             }  
 8             return new String("false");  
 9         }  
10       
11         @SuppressWarnings("unchecked")  
12         public Class getObjectType() {  
13             return flag ? Date.class : String.class;  
14         }  
15       
16         public boolean isSingleton() {  
17             return false;  
18         }  
19       
20         public void setFlag(boolean flag) {  
21             this.flag = flag;  
22         }  
23     }  
 1     <bean id="factoryBeanOne" class="com.study.demo.factorybean.SimpleFactoryBean" >  
 2         <property name="flag">  
 3             <value>true</value>  
 4         </property>  
 5     </bean>  
 6       
 7     <bean id="factoryBeanTwo" class="com.study.demo.factorybean.SimpleFactoryBean" >  
 8         <property name="flag">  
 9             <value>false</value>  
10         </property>  
11     </bean>  
1     public class MainTest {  
2         public static void main(String[] args) {  
3             Resource res = new ClassPathResource("bean.xml");  
4             BeanFactory factory = new XmlBeanFactory(res);  
5             System.out.println(factory.getBean("factoryBeanOne").getClass());  
6             System.out.println(factory.getBean("factoryBeanTwo").getClass());  
7         }  
8     }  

该类输出如下: 
class java.util.Date 
class java.lang.String 
也就是说,容器通过getBean方法返回的不是FactoryBean本身,而是FactoryBean实现类中getObject()方法所返回的对象。 

 

原文地址:https://www.cnblogs.com/2015110615L/p/6664468.html