BeanFactory提供的是最基本的IOC容器的功能,关于这些功能定义,我们可以在接口BeanFactory中看到。
BeanFactory接口定义了IOC容器最基本的形式,并且提供了IOC容器所应该遵守的最基本的服务契约,同时,这也是我们使用IOC容器所应遵守的最底层和最基本的编程规范,这些接口定义勾画出了IOC的基本轮廓。很显然,在Spring的代码实现中,BeanFactory只是一个接口类,并没有给出容器的具体实现,而我们在图1中看到的各种具体类,比如
DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等都可以看成是容器附加了某种功能的具体实现,也就是容器体系中的具体容器产品。下面我们来看看图1中BeanFactory是怎样定义IOC容器的基本接口的。
图1
用户使用容器时,可以使用转义符"&"来得到FactoryBean本身,用来区分通过容器来获取的FactoryBean产生的对象和获取FactoryBean本身。举例来说,如果myJndiObject是一个FactoryBean,那么使用&myJndiObject得到的是FactoryBean,而不是myJndiObject这个FactoryBean产生出来的对象。关于具体的FactoryBean的设计和实现模式,我们会在后面的内容中介绍。
注意:理解上面的这段话需要很好的区分FactoryBean和BeanFactory这两个在Spring中使用频率很高的类,它们在拼写上非常相似。一个是Factory,也就是IOC容器或对象工厂;一个是Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean部署简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
BeanFactory接口设计了getBean方法,这个方法是使用IOC容器API的主要方法,通过这个方法,可以取得IOC容器管理中管理的Bean,Bean的取得是通过指定的名字来索引的。如果需要在获取Bean时需要对Bean的类型进行检查,BeanFactory接口定义了带有参数的getBean方法,这个方法使用与不带参数的getBean方法类似,不同的是增加了对Bean检索的类型的要求。
用户可以通过BeanFactory接口方法中的getBean来使用Bean的名字,从而在获取Bean时,如果需要获取的Bean是prototype类型的,用户还可以为这个protoptype类型的Bean生成指定 构造函数对应参数。这使得在一定程度上可以控制生成protopyte类型的Bean。有了BeanFactory的定义,用户可以执行以下操作:
1.通过接口方法cotainsBean让用户能够判断容器是否含有指定名字的Bean。
2.通过接口方法isSingleton来查询指定名字的Bean是否是Singleton类型的Bean。对于Singleton属性,用户可以在BeanDefinition中指定。
3.通过接口方法isProtopyte来查询指定名字的Bean是否是Protopyte类型的Bean。对于Protopyte属性,用户同样可以在BeanDefinition中指定。
4.通过接口方法isTypeMatch来查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
5.通过接口方法getType来查询指定名字的Bean的Class类型。
6.通过接口方法getAliases来查询指定了名字的Bean的所有别名,这些别名都是用户在BeanDefinition中定义的。
这些定义的接口方法勾画出了IOC容器的基本特性。因为这个BeanFactory接口定义了IOC容器,所以下面给出了它定义的全部内容供大家参考,如下:
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name,Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
可以看到,这里定义的只是一系列的接口方法,通过一系列的BeanFactory接口,可以使用不同的Bean检索方法,很方便的从IOC容器中得到需要的Bean,从而忽略具体的IOC容器的实现,从这个角度上看,这些检索方法代表的是最为基本的容器入口。