BeanFactory
BeanFactory是spring容器的顶级接口,或者就是源码说的root,根接口。
1 | /** |
BeanFactory不能够被实例化,而是定义了一套所有IOC容器必须遵守的规范。可以看看BeanFactory的结构,如下
多个重载方法,getBean(),从spring容器中获取bean对象。 containsBean()判断spring容器中是否包含某个bean。 还有判断bean的作用域,即是否为单例bean或者多例bean的方法,isSingleton和isPrototype,还有根据bean的名字获取名字等等…
具体的容器可以对其进行功能的增加,像spring中用到比较多的ApplicationContext,就是BeanFactory的子类。而ApplicationContext接口又衍生了很多的子类,像比较熟悉的ClassPathXmlApplicationContext、 AnnoationConfigApplicationContext。
FactoryBean
FactoryBean也是一个接口,可以看官方注释如下:
1 | /** |
第一句话我自己不是很明白,可能他的意思是BeanFactory提供了spring容器的规范,实现了BeanFactory的类或接口中所使用的对象或实例,这些对象都可以作为单一对象的工厂。可能是想说明一个bean可以作为一个生产bean对象的工厂?
接下来就清晰了一点,如果一个bean实现了FactoryBean这个接口,则它可以作为工厂来暴露对象,而不是把自己作为一个bean实例暴露,好像也很好的解释了前一句话,实现这个接口的bean可以作为工厂bean来生产bean。。。
最关键的就是最后一句,如果一个bean实现了FactoryBean,则说明它是一个工厂bean,但是,此时我们getBean() 来获取这个bean时,我们得到的不是它本身,而是它创建出来的对象,他创建出来的对象是什么? 正如它的注释里面的—– getObject()。
举个例子,我们编写一个User类,并将其注入spring容器中。
1 |
|
1 | <bean id="myUser" class="User" > |
在写一个类实现FactoryBean接口,如下:
1 | import org.springframework.beans.factory.FactoryBean; |
同样,注入spring容器
1 | <bean id="userBean" class="UserBean"> </bean> |
可以来测试一下,通过getBean的方式来从spring容器中获取bean,结果userBean得到的结果是User类。
1 |
|
输出结果:
1 | User |
这是因为UserBean实现了FactoryBean接口,那么他就是一个工厂bean,它生产的bean是根据方法GetObject() 确定的,如果想要得到改对象,在bean的名字前面加上“&”即可。
1 | Object userBean = context.getBean("&userBean"); |
总结
BeanFactory是spring的bean工厂,它是负责生产和管理bean的工厂,给spring容器提供了一系列的规范,所有的容器都必须遵守这一规范。
FactoryBean是在spring容器的基础上,给bean的实现加上一个简单的工厂模式,即生产bean的方式更加灵活了,我们可以在getObject() 方法中指定需要生产bean的类型。