Spring源码了解

"3,了解IOC容器的设计"

Posted by Dunno on August 22, 2016

目录

背景介绍

我们学习一下容器具体是怎么启动的

我这里学习的spring4的代码,和spring3的有些出入。可以checkout 4.x版本观看

参考资料

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/

spring 技术内幕

IOC容器结构

拿FileSystemXmlApplicationContext做例子,我们来看一下它的类图:
图片如果不清楚,可以右键保存下来看。

IOC容器结构

通常我们使用spring时,最直接的感受就是不用new对象了,spring已经直接帮我们实现new好了,然后放到一个容器里面,我们每次注入的时候实际就是去容器里面去拿。

上面的图主要有三大部分,一个是xxxBeanFactory,一个是xxxApplicationContext,一个是ResourceLoader,还有一些其他的接口,比如ApplicationEventPublisher(事件发布),我们后面再学习。

xxxBeanFactory

beanFactory bean的工厂,顾名思义,这个xxxBeanFactory就是容器了。我们其实就可以理解成装实体的桶子就行了,那么beanFactory里面封装的方法都是和[容器属性]相关的方法。比如如果我们设计,我们可以第一想到:容器多大啊,能装多少东西啊,装了啥啊之类的东西。

BeanFactory


//封装了一些基本的访问bean的方法
public interface BeanFactory {
	//&xxxbean对象拿到的是xxxbean对应的factorybean
	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;

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

	boolean containsBean(String name);

	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	String[] getAliases(String name);

}

HierarchicalBeanFactory


//在BeanFactory基础上加了获得父BeanFactory的方法
public interface HierarchicalBeanFactory extends BeanFactory {

	BeanFactory getParentBeanFactory();

	boolean containsLocalBean(String name);

}

ConfigurableBeanFactory

在HierarchicalBeanFactory的基础上增加了一些对BeanFactory的配置功能,比如setParentBeanFactory()设置双亲IOC容器。

ListableBeanFactory

在BeanFactory基础上增加了对容器bean的各种属性查询方法。

ResourceLoader

ResourceLoader,顾名思义:资源加载者。前面讲到了把beanFactory理解成装实体的桶子,那么我们到怎么装呢?到哪里去装呢?这就是ResourceLoader负责的了。


public interface ResourceLoader {
	//这个值是classpath:  方便classpathresource时使用
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
	//获得资源,也就是告诉你装东西的地址
	Resource getResource(String location);
	//
	ClassLoader getClassLoader();

}

xxxApplicationContext

它是一个更高级的容器,容器只是它的一个子功能,同时它还支持其他特性:

  • 支持国际化 多语言版本的支持(MessageSource)
  • 访问资源 容器加载bean是要有一个加载源的,这个resource就是加载源。
  • 支持应用事件 在整个bean的声明周期中,需要引入应用事件,便于更好的管理。

applicationContext怎么理解呢,你就把它理解成一个工具箱,里面放了桶子(xxBeanFactory),还放了给桶子装东西的方法(resourcesLoader),还有中英文说明书(MessageSource),还有遥控器可以遥控桶子(ApplicationEventPublisher)。有了这些大工具箱,你能想到的启动容器的条件是不是就都具备了!