IOC容器的設計

本節來學習IOC容器的設計:

IOC容器的設計UML:

  • 從接口BeanFactory到HierarchicalBeanFactory,再到ConfigurableBeanFactory,是一條主要的beanFactory的設計路徑。其中,BeanFactory接口定義了基本的IOC容器的規範。在這個接口定義中,包含了getBean()這樣的IOC容器的基本方法。而HierarchicalBeanFactory接口繼承了BeanFactory的基本接口後,增加了getParentBeanFactory()的接口功能,使BeanFactory具備了雙親Ioc容器的管理功能。在接下來的ConfigurableBeanFactory接口中,主要定義了一些對BeanFactory的配置功能,比如通過setParentBeanFactory設置雙親Ioc容器,通過addBeanPostProcessor配置Bean的後置處理器,等等。
  • 從BeanFactory到ListableBeanFactory到ApplicationContext再到WebApplicationContext或者ConfigurableApplicationContext接口,是一條以ApplicationContext應用上下文接口爲核心的接口設計。ListableBeanFactory細化了許多BeanFactory的接口功能,如定義了getBeanDefinitionNames接口方法,ApplicationContext通過繼承MessageSource、ApplicationEventPublisher、ResourcePatternResolver接口,在BeanFactory簡單IOC容器的基礎上添加了許多對高級容器的特性的支持。
  • DefaultListableBeanFactory這個基本的IOC容器就是實現了ConfigurableListableBeanFactory、BeanDefinitionRegistry從而成爲一個簡單IOC容器的實現。


1.BeanFactory的應用場景:

用戶在使用容器時,可以使用&得到FactoryBean本身,用來區分通過容器來獲取FactoryBean產生的對象和獲取FactoryBean本身。

public interface BeanFactory {

	/**
	 * 通過名稱獲取bean
	 */
	Object getBean(String name) throws BeansException;

	/**
	 * 通過名稱和類型獲取Bean
	 */
	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

	/**
	 * 
	 */
	Object getBean(String name, Object... args) throws BeansException;

	/**
	 * 通過類型獲取Bean
	 */
	<T> T getBean(Class<T> requiredType) throws BeansException;

	/**
	 * 
	 */
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;


	/**
	 * 判斷容器是否含有指定名字的Bean
	 */
	boolean containsBean(String name);

	/**
	 * 查詢指定名字的Bean是否是單例類型的
	 */
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 查詢指定名字的Bean是否是prototype類型的
	 */
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 指定了名字的Bean的Class類型是否是特定的Class類型
	 */
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * 指定了名字的Bean的Class類型是否是特定的Class類型
	 */
	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * 查詢指定名字的Bean的Class類型
	 */
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 查詢指定了名字的Bean的所有別名
	 */
	String[] getAliases(String name);

2.BeanFactory容器的設計原理

XmlBeanFactory設計的類繼承關係:


注意:XmlBeanFactory在最新的版本中已經不建議使用

在Spring中,實際上DefaultListableBeanFactory作爲一個默認的功能完整的IOC容器來使用的。XmlBeanFactory在繼承了DefaultListableBeanFactory容器功能的同時,增加了新的功能,可以讀取以XML文件方式定義的BeanDefinition的IOC容器。

XMl讀取的功能,是在XmlBeanFactory類中初始化了一個XmlBeanDefinitionReader對象,這個對象可以處理XMl文件讀取。

@Deprecated
@SuppressWarnings({"serial", "all"})
public class XmlBeanFactory extends DefaultListableBeanFactory {

	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

	public XmlBeanFactory(Resource resource) throws BeansException {
		this(resource, null);
	}

	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}

}


3.ApplicationContext的應用場景

ApplicationContext是一個高級形態的IOC容器

3.1支持不同的信息源。ApplicationContext擴展了MessageSource接口,這些信息源的擴展功能可以支持國際化的實現,爲開發多語言版本的應用提供服務。

3.2訪問資源。這點體現在對ResourceLoader的支持上,可以從不同地方得到Bean的資源。

3.3支持應用事件。繼承了接口ApplicationEventPublisher,從而在上下文中引入事件機制。這些事件和Bean的生命週期的結合爲Bean的管理提供了便利。


4.ApplicationContext容器的設計原理

以FileSystemXmlApplicationContext實現類爲例子,可以看到主要功能已經在基類AbstractXmlApplicationContext實現了,在FileSystemXmlApplicationContext中,作爲一個具體的應用上下文,只需要實現兩個功能:

	public FileSystemXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

啓動IOC容器的refresh,後續再展開。

另一個功能是從文件系統中加載XMl的Bean定義資源

	@Override
	protected Resource getResourceByPath(String path) {
		if (path.startsWith("/")) {
			path = path.substring(1);
		}
		return new FileSystemResource(path);
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章