beanFactory 是spring IoC中一個最基本的容器,位於繼承圖最頂端的一個接口。spring IoC容器的接口/類設計圖如下所示(注:該圖只包含部分接口或子類):
圖 1.1(圖片來源於http://www.pinhuba.com/spring/101250.htm)
作爲一個最古老的祖先接口,beanFactory接口定義了一個容器應該具備的最基本的功能規範。舉個現實生活中的例子,如果把容器比作一個水桶,那麼beanFactory就定義了水桶所具備的最基本功能,比如說,可以裝水、有個提手。爲了滿足不同場合的需求,在滿足了最基本功能之後,還可以添加更復雜的功能,比如說抗高溫、耐磨、輕便等。同理,在spring IoC容器中,子接口或子類繼承祖先接口beanFactory之後,可以添加新新的功能。比如說HierarchicalBeanFactory添加了getParentBeanFactory 和 containsLocalBean兩個方法。水桶有各種各樣的種類,比如說塑料水桶、鋁製水桶,同樣spring 容器中有基於XML的容器、有基於註解的configurable容器。但是不管什麼水桶,都要有一個最基本的功能:裝水。對於任何一個spring 具體容器,它都需要滿足beanFactory這個接口的定義。那麼beanFactory定義了哪些功能呢?如下圖所示:
圖 1.2
唯一的一個字段 FACTORY_BEAN_PREFIX是用來區分factory bean 和factory 產生的bean。在spring中,所有的bean都是由factory產生和管理的,factory本身也是一個bean,所以這個字段就是用來區分被factory管理的普通 bean和factory bean的。這個字段的定義爲:
String FACTORY_BEAN_PREFIX = "&";
通過“&”可以得到factory bean。比如說 myJndiObject 是一個普通bean,那麼 &myJndiObject 返回一個factory bean。
beanFactory有很多間接子類,這裏以XmlBeanFactory爲例,簡單分析一下。它的類繼承圖如圖1.1紅色虛線框所示。DefaultListableBeanFactory是一個功能比較完整的容器,XmlBeanFactory在繼承DefaultListableBeanFactory之後,增加了一個可以讀取以XML文件的方法,XML文件包含了bean的定義。其代碼實現如下:
public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); /** * Create a new XmlBeanFactory with the given resource, * which must be parsable using DOM. * @param resource XML resource to load bean definitions from * @throws BeansException in case of loading or parsing errors */ public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } /** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * @param resource XML resource to load bean definitions from * @param parentBeanFactory parent bean factory * @throws BeansException in case of loading or parsing errors */ public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); } }
reader字段會讀取bean的定義。參考XmlBeanFactory的實現,我們可以在程序中直接使用DefaultListableBeanFactory,實現和XmlBeanFactory類似的功能。
ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
這段代碼實現瞭如下功能:
- 創建配置文件的抽象資源,這個抽象文件包含了BeanDefinition的定義;
- 創建一個BeanFactory;
- 創建一個載入BeanDefinition的讀取器。使用XmlBeanDefinitionReader來讀取XML文件形式的BeanDefinition;
- 從定義好的資源位置讀入配置信息。讀取之後,由其它容器解析、註冊。