Spring中有两种类型的Bean,一种是普通Bean,另外一种是工厂Bean,即FactoryBean,这两种Bean都被容器管理,但工厂Bean跟普通Bean不一样,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。在Spring框架内部,有不少地方有FactoryBean的实现类,它们在不少应用如(Spring的AOP、ORM、事务管理)及与其它第三框架(ehCache)集成时都有体现:缓存
FactoryBean的使用框架
通常状况下,Spring经过反射机制利用bean的class属性指定实现类来实例化bean 。在某些状况下,实例化bean过程比较复杂,若是按照传统的方式,则须要在<bean>中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会获得一个简单的方案。Spring为此提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,用户能够经过实现该接口定制实例化bean的逻辑。this
FactoryBean接口对于Spring框架来讲占有重要的地位,Spring 自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。从Spring 3.0 开始, FactoryBean开始支持泛型,即接口声明改成FactoryBean<T> 的形式:
编码
在该接口中还定义了如下3个方法。prototype
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()方法。例如:若是使用传统方式配置下面Car的<bean>时,Car的每一个属性分别对应一个<property>元素标签。事务
若是用FactoryBean的方式实现就会灵活一些,下例经过逗号分割符的方式一次性地为Car的全部属性指定配置值:
作用域
有了这个CarFactoryBean后,就能够在配置文件中使用下面这种自定义的配置方式配置Car Bean了:
当调用getBean("car") 时,Spring经过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。若是但愿获取CarFactoryBean的实例,则须要在使用getBean(beanName) 方法时在beanName前显示的加上 "&" 前缀,例如getBean("&car")。