Spring 中有两个最最基本的接口:BeanFactory 与 FactoryBean,可以说是核心中的核心。
简单的说,BeanFactory就是容器提供给使用者获取Bean的接口,Spring中的ApplicationContext 就是实现了这个接口。粗糙的理解:BeanFactory就是容器。
而FactoryBean则是产生Bean的工厂,许多时候,简单的通过Spring 实例化一个Bean,并不能满足我们的需求,最明显的例子就是数据库的连接池,这个连接池就是一个FactoryBean。Spring 如果发现某个Bean实现了FactoryBean,那么当调用者取这个Bean的时候,不是直接返回这个Bean,而是去调用这个Bean的getObject(),再返回结果。
FactoryBean的定义很简单,只有三个方法:
public interface FactoryBean<T> {
T getObject() throws Exception; // 拿到一个Bean
Class<?> getObjectType(); //返回Bean的类型
boolean isSingleton(); //是否单例
}
再看一个例子,hibernate的sessionFactory的配置(我们实际需要的是一个SessionFactory对象,但配置中却是LocalSessionFactoryBean类,为啥?就是因为LocalSessionFactoryBean返回的是SessionFactory)
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean>
LocalSessionFactoryBean 就是实现了FactoryBean的接口,
public class LocalSessionFactoryBean extends HibernateExceptionTranslator
implements FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean {
.....其它代码........
private SessionFactory sessionFactory;
.....其它代码........
@Override //设置完参数后,产生sessionFactory
public void afterPropertiesSet() throws IOException {
.....其它代码........
this.sessionFactory = buildSessionFactory(sfb);
}
@Override //返回sessionFactory
public SessionFactory getObject() {
return this.sessionFactory;
}
.....其它代码........
}
如果要得到FactoryBean 本身,加一个&,如下面的代码
//从这个FactoryBean中得到一个对象
System.out.println(act.getBean("sessionFactory"));
//如果要得到FactoryBean 本身,加一个&
System.out.println(act.getBean("&sessionFactory"));