Spring5源码 - ApplicationContext(高级容器)
ApplicationContext 称为高级容器的原因是其继承了多个接口,具备更多的功能。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory, MessageSource,
ApplicationEventPublisher, ResourcePatternResolver {...}
1、继承的接口
(1)EnvironmentCapable
该接口主要用于获取容器的启动参数,例如 -Dparam=1 。对于Web而言,还可以通过getEnvironment()访问到Servlet的一些配置信息,例如获取到web.xml中的 classpath:spring/spring-*.xml配置文件。
public interface EnvironmentCapable {
Environment getEnvironment();
}
(2)ListableBeanFactory
可以通过列表(批量)的方式来管理bean。
(3)HierarchicalBeanFactory
支持多层级的容器,来实现对每一层Bean的管理。
public interface HierarchicalBeanFactory extends BeanFactory {
@Nullable
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String var1);
}
(4)ResourcePatternResolver
可以用于加载文件
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String var1) throws IOException;
}
(5)MessageSource
管理Message,进而实现国际化的功能
(6)ApplicationEventPublisher
支持事件的发布能力的监听。
2、常用容器
(1)传统的基于XML配置的经典容器
FileSystemXmlApplicationContext:从文件系统中加载配置
ClassPathXmlApplicationContext:从classpath加载配置
XmlWebApplicationContext:用于Web应用程序的容器
(2)基于注解配置的容器
在Spring的包下:
- AnnotationConfigApplicationContext
org.springframework.boot.web.servlet.context 包下:
-
AnnotationConfigServletWebApplicationContext
-
AnnotationConfigReactiveWebApplicationContext:响应式编程容器
3、高级容器的共性
refresh() 方法大致功能(后面一篇文章单独讲):
- 容器初始化、配置解析
- BeanFactoryPostProcessor、BeanPostProcessor的注册与激活
- 国际化配置
- …
ApplicationContext 接口中都是get方法,只提供读取操作,容器都是需要配置的,需要子接口来提供可配置的能力,这个接口就是 ConfigurableApplicationContext :
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
// 具备可配置能力
void setId(String id);
void setEnvironment(ConfigurableEnvironment environment);
...
// 具备启动刷新和关闭容器的能力
void refresh()
void close();
...
}
该接口除了继承ApplicationContext外,还继承了下面两个接口:
Lifecycle
用于对容器生命周期的管理
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
Closeable
该接口来自于JDK,用于关闭容器时释放资源。
package java.io;
public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}
在ApplicationContext被关闭的情况下,refresh() 可以重新启动容器。
在ApplicationContext 在启动的情况下,refresh() 可以清楚缓存并重新装配配置信息。
ApplicationContext 大部分的具体实现主要存在于AbstractApplicationContext类中:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 调用容器准备刷新的方法,获取容器的启动时间,同时给容器设置同步标识
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 告诉子类启动refreshBeanFactory0方法,Bean定义资源文件的载入从
// 子类的refreshBeanFactory0方法启动,里面有抽象方法
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 为BeanFactory配置容器特性:事件处理器、类加载器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 为容器的某些子类指定特殊的BeanPost事件处理器,钩子方法
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
}