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);
	}

猜你喜欢

转载自blog.csdn.net/dxh0823/article/details/80649073
今日推荐