1. Spring的资源抽象接口
假如有一个文件位于Web应用的类路径下,用户可以通过以下方式对这个文件资源进行访问:
- 通过
FileSystemResource以文件系统绝对路径的方式进行访问; - 通过
ClassPathResource以类路径的方式进行访问; - 通过
ServletContextResource以相对于Web应用根目录的方式进行访问。 
2. BeanFactory的类体系结构

BeanFactory:位于类结构树的顶端,最主要的方法是getBean(String beanName),从容器中返回特定类型的beanListableBeanFactory:该接口定义了访问容器中Bean基本信息的若干方法HierarchicalBeanFactory:父子级联IoC容器的接口,子容器可以通过接口方法访问父容器ConfigurableBeanFactory:增强了IoC容器的可定制性AutowireCapableBeanFactory:定义了将容器中的bean按照某种规则进行自动装配的方法SingletonBeanRegistry:定义了允许在运行期向容器注册单实例bean的方法BeanDefinitionRegistry:每一个bean在容器中通过BeanDefinition对象表示,BeanDefinitionRegistry定义了向容器手工注册bean的方法- Spring在
DefaultSingletonBeanRegistry类中提供了一个用于缓存单实例bean的缓存器,以HashMap实现,单实例的bean以beanName为key保存在这个HashMap中 
3. ApplicationContext的类体系结构

ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了ApplicationListener事件监听接口的Bean 可以接收到容器事件,并对事件进行响应处理。在ApplicationContext抽象实现类AbstractApplicationContext中,我们可以发现存在一个ApplicationEventMulticaster,它负责保存所有监听器,以便在容器产生上下文事件时通知这些事件监听者。MessageSource:为应用提供i18n国际化消息访问的功能;ResourcePatternResolver:所有ApplicationContext实现类都实现了类似于PathMatchingResourcePatternResolver的功能,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。LifeCycle:该接口是Spring 2.0加入的,该接口提供了start()和stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被ApplicationContext实现及具体Bean实现,ApplicationContext会将start/stop的信息传递给容器中所有实现了该接口的Bean,以达到管理和控制JMX、任务调度等目的。ConfigurableApplicationContext扩展于ApplicationContext,它新增加了两个主要的方法:refresh()和close(),让ApplicationContext具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用refresh()即可启动应用上下文,在已经启动的状态下,调用refresh()则清除缓存并重新装载配置信息,而调用close()则可关闭应用上下文。
4. WebApplicantContext体系结构
- 它允许从相对于Web根目录的路径中加载配置文件完成初始化工作。从
WebApplicationContext中可以获取ServletContext引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便Web应用环境可以访问spring上下文。 WebApplicationContext扩展了ApplicationContext,WebApplicationContext定义了一个常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文启动时,我们可以直接通过下面的语句从web容器中获取WebApplicationContext:
1  | WebApplicationContext wac=(WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);  | 
5. BeanFactory中Bean的生命周期
5.1 Bean生命周期
- 如果容器注册
InstantiationAwareBeanPostProcessor接口,调用postProcessBeforeInstantiation方法 - Bean的实例化(调用默认构造器)
 - 如果容器注册
InstantiationAwareBeanPostProcessor接口,调用postProcessAfterInstantiation方法 - 如果容器注册
InstantiationAwareBeanPostProcessor接口,调用postProcessPropertyValues方法 - 根据配置设置属性值
 - 如果Bean实现了
BeanNameAware接口,调用BeanNameAware接口的setBeanName方法 - 如果Bean实现了
BeanFactoryAware接口,调用BeanFactoryAware接口的setBeanFactory方法 - 如果容器注册了
BeanPostProcessor接口,调用BeanPostProcessor接口的postProcessBeforeInitialization方法 - 如果Bean实现了
InitializingBean接口,调用InitializingBean接口的afterPropertiesSet方法 - 通过
init-method属性配置的初始方法 - 如果容器注册了
BeanPostProcessor接口,调用BeanPostProcessor接口的postProcessAfterInitialization方法 - 如果是单例模式,将Bean放入缓存池中;容器销毁时,调用
DisposableBean的destroy方法;最后调用destroy-method方法 - 如果是多例模式,将Bean交给调用者。
 
5.2 初始化过程中的方法分类
- bean自身的方法:如调用bean构造函数实例化bean,调用
Setter设置bean的属性值,以及通过<bean>的init-method和destory-method所指定的方法; - bean级生命周期接口方法:如
BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean,这些接口方法由bean类直接实现; - 容器级生命周期接口方法:如
InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口实现,一般称它们的实现类为“后处理器”。 
5.3 说明
- Spring的AOP等功能即通过
BeanPostProcessor实现 - 如果
<bean>通过init-method属性定义了初始化方法,将执行这个方法 - 如果bean的作用范围为
scope="prototype",将bean返回给调用者之后,调用者负责bean的后续生命的管理,Spring不再管理这个bean的生命周期;如果scope="singleton",则将bean放入到Spring IoC容器的缓存池中,并将bean的引用返回给调用者,Spring继续管理这些bean的后续生命周期 - 对于单例的bean,当容器关闭时,将触发Spring对bean的后续生命周期的管理工作。如果bean实现了
DisposableBean接口,则将调用接口的destroy()方法 - 对于单例的bean,如果通过
destroy-method指定了bean的销毁方法,Spring将执行这个方法 - 后处理器的实际调用顺序和注册顺序无关,在具有多个后处理器的情况下,必须通过实现
org.springframework.core.Ordered接口确定调用顺序 
5.4 测试
applicationContext.xml
1  | <?xml version="1.0" encoding="UTF-8"?>  | 
Car
1  | package com.data;  | 
MyBeanPostProcessor
1  | package com.beanfactory;  | 
TestBeanFactory
1  | package config;  | 
- 结果
 
1  | 二月 09, 2017 10:58:59 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions  | 
6. ApplicationContext中的Bean生命周期
6.1 流程图
6.2 说明
- 如果bean实现了
org.springframework.context.ApplicationContextAware接口,会增加一个调用该接口方法setApplicationContext()的步骤 - 如果配置文件中声明了工厂后处理器接口
BeanFactoryPostProcessor的实现类,则应用上下文在加载配置文件之后、初始化bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理 ApplicationContext和BeanFactory的不同之处在于:前者会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而后者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册- 对bean的初始化,
BeanFactory发生在第一次调用bean时,而ApplicationContext发生在初始化容器时 
6.3 测试
MyBeanPostProcessor同上Car增加对ApplicationContextAware接口的实现,并添加@PostConstruct和@PreDestroy的注解方法
1  | package com.data;  | 
MyBeanFactoryPostProcessor
1  | package com.beanfactory;  | 
- 基于Java类的Spring配置:
AnnotationBeans 
1  | package config;  | 
TestApplicationContext
1  | package config;  | 
- 结果
 
1  | 二月 09, 2017 11:55:25 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh  | 
7. 容器内部工作机制
7.1 启动源码
Spring的AbstractApplicationContext的refresh()方法定义了Spring容器在加载配置文件后的各项处理工作
1  | 
  | 
7.2 容器启动流程
ContextLoaderListener通过调用继承自ContextLoader的initWebApplicationContext方法实例化SpringIoC容器。在实例化Spring IoC容器的过程中,最主要的两个方法是createWebApplicationContext和configureAndRefreshWebApplicationContext方法。createWebApplicationContext方法用于返回XmlWebApplicationContext实例,即Web环境下的SpringIoC容器。configureAndRefreshWebApplicationContext用于配XmlWebApplicationContext,读取web.xml中通过contextConfigLocation标签指定的XML文件,通过调用refresh来调用AbstractApplicationContext中的refresh初始化。
BeanFactory实例化XML文件中配置的bean,Spring将配置文件的bean的信息解析成为一个个的BeanDefinition对象并装入到容器的Bean定义注册表,但此时Bean还未初始化;obtainFreshBeanFactory()会调用自身的refreshBeanFactory(),而refreshBeanFactory()方法由子类AbstractRefreshableApplicationContext实现,该方法返回了一个创建的DefaultListableBeanFactory对象,这个对象就是由ApplicationContext管理的BeanFactory容器对象;- 调用工厂后处理器:根据反射机制从
BeanDefinitionRegistry中找出所有BeanFactoryPostProcessor类型的Bean,并调用其postProcessBeanFactory()接口方法。经过第一步加载配置文件,已经把配置文件中定义的所有bean装载到BeanDefinitionRegistry这个Beanfactory中,对于ApplicationContext应用来说这个BeanDefinitionRegistry类型的BeanFactory就是Spring默认的DefaultListableBeanFactory - 注册Bean后处理器:根据反射机制从
BeanDefinitionRegistry中找出所有BeanPostProcessor类型的Bean,并将它们注册到容器Bean后处理器的注册表中; - 初始化消息源:初始化容器的国际化信息资源;
 - 初始化应用上下文事件广播器;
 - 初始化其他特殊的Bean;
 - 注册事件监听器;
 - 初始化singleton的Bean:实例化所有singleton的Bean,并将它们放入Spring容器的缓存中;
 - 发布上下文刷新事件:在此处时容器已经启动完成,发布容器
refresh事件创建上下文刷新事件,事件广播器负责将些事件广播到每个注册的事件监听器中。 
7.3 Bean加载流程
ResourceLoader从存储介质中加载Spring配置文件,并使用Resource表示这个配置文件的资源;BeanDefinitionReader读取Resource所指向的配置文件资源,然后解析配置文件。配置文件中每一个<bean>解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中;- 容器扫描
BeanDefinitionRegistry中的BeanDefinition,使用Java的反射机制自动识别出Bean工厂后处理器(实现BeanFactoryPostProcessor接口)的Bean,然后调用这些Bean工厂后处理器对BeanDefinitionRegistry中的BeanDefinition进行加工处理。主要完成以下两项工作:- 对使用到占位符的
<bean>元素标签进行解析,得到最终的配置值,这意味对一些半成品式的BeanDefinition对象进行加工处理并得到成品的BeanDefinition对象; - 对
BeanDefinitionRegistry中的BeanDefinition进行扫描,通过Java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean),并自动将它们注册到Spring容器的属性编辑器注册表中(PropertyEditorRegistry); 
 - 对使用到占位符的
 - Spring容器从
BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手进行Bean实例化的工作; - 在实例化Bean时,Spring容器使用
BeanWrapper对Bean进行封装,BeanWrapper提供了很多以Java反射机制操作Bean的方法,它将结合该Bean的BeanDefinition以及容器中属性编辑器,完成Bean属性的设置工作; - 利用容器中注册的Bean后处理器(实现
BeanPostProcessor接口的Bean)对已经完成属性设置工作的Bean进行后续加工,直接装配出一个准备就绪的Bean。 
8. Spring事件
Spring事件体系包括三个组件:事件,事件监听器,事件广播器。
- 事件:
ApplicationEvent - 事件监听器:
ApplicationListener,对监听到的事件进行处理。 - 事件广播器:
ApplicationEventMulticaster,将Spring publish的事件广播给所有的监听器。Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。 AbstractApplicationContext拥有一个applicationEventMulticaster成员变量,applicationEventMulticaster提供了容器监听器的注册表。
8.1 事件广播器的初始化
1  | private void initApplicationEventMulticaster() throws BeansException {  | 
用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster就可以了,Spring会通过反射的机制将其注册成容器的事件广播器,如果没有找到配置的外部事件广播器,Spring自动使用 SimpleApplicationEventMulticaster作为事件广播器。
8.2 注册事件监听器
1  | private void registerListeners () throws BeansException {  | 
Spring根据反射机制,使用ListableBeanFactory的getBeansOfType方法,从BeanDefinitionRegistry中找出所有实现 org.springframework.context.ApplicationListener的Bean,将它们注册为容器的事件监听器,实际的操作就是将其添加到事件广播器所提供的监听器注册表中。
8.3 发布事件
1  | public void publishEvent(ApplicationEvent event) {  | 
在AbstractApplicationContext的publishEvent方法中, Spring委托ApplicationEventMulticaster将事件通知给所有的事件监听器
8.4 Spring默认的事件广播器SimpleApplicationEventMulticaster
1  | public void multicastEvent( final ApplicationEvent event) {  | 
遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法。
由于SimpleApplicationEventMulticaster的taskExecutor的实现类是SyncTaskExecutor,因此,事件监听器对事件的处理,是同步进行的。
8.5 举例
springEvent.xml
1  | <?xml version="1.0" encoding="UTF-8"?>  | 
MockEvent
1  | package com.event;  | 
MockEventListener
1  | package com.event;  | 
MockEventPublisher
1  | package com.event;  | 
MockEventTest
1  | package com.event;  | 
- 结果
 
1  | 二月 09, 2017 9:57:43 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh  |