目录
背景介绍
我们学习一下容器具体是怎么启动的
我这里学习的spring4的代码,和spring3的有些出入。可以checkout 4.x版本观看
参考资料
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
spring 技术内幕
IOC容器结构
拿FileSystemXmlApplicationContext做例子,我们来看一下它的类图:
图片如果不清楚,可以右键保存下来看。
通常我们使用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)。有了这些大工具箱,你能想到的启动容器的条件是不是就都具备了!