一、ApplicationContext
ApplicationContext是spring继BeanFactory之外的另一个核心接口或容器,允许容器通过应用程序上下文环境创建、获取、管理bean。
在Spring 中, BeanFactory 接口的各种实现负责bean实例化,为Spring 管理的bean提供依赖注入和生命周期支持。然而,作为BeanFactory接口的扩展, ApplicationContext 还提供其他有用的功能。ApplicationContext 的主要功能是提供一个更丰富的框架来构建应用程序。ApplicationContext 更加了解所配置的bean(与BeanFactory 相比), 在使用Spring 基础结构类和接口(例BeanFactoryPostProcessor) 的情况下,ApplicationContext 可以代替你与这些类或接口进行交互, 从而减少为了使用Spring 所需编写的代码量。
使用ApplicationContext 的最大好处是,它允许以完全声明的方式配置和管理Spring 以及Spring 所管理的资源。这意味着Spring 尽可能提供支持类来自动将ApplicationContext 加载到应用程序中,从而不需要编写任何代码来访问ApplicationContext。
二:常见的ApplicationContext
spring为ApplicationContext提供了很多实现类,其中有四个比较常用的:
ClassPathXmlApplicationContext
通过读取工程src目录下的配置文件启动ioc容器
ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml ");
FileSystemXmlApplicationContext
通过读取系统文件路径下的配置文件启动ioc容器
ApplicationContext context = new FileSystemXmlApplicationContext( "D:/test/applicationContext.xml ");
AnnotationConfigWebApplicationConetxt
通过配置类的方式启动ioc容器
uml如图:
三、ioc容器的初始化
可以看到以上ApplicationContex都有个父类是AbstractApplicationContext,refresh()方法是该父类的方法,在ioc容器的启动过程中都会走调用refresh()方法,refresh 函数中包含了几乎ApplicationContext 中提供的全部功能,而且此函数中逻辑非常清晰明了, 使我们很容易分析对应的层次及逻辑:
public void refresh() throws BeansException , IllegalStateException {
synchronized (this. startupShutdownMonitor) {
//准备刷新的上下文环境
prepareRefresh() ;
//初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() ;
//对BeanFactory 进行各种功能填充
prepareBeanFactory(beanFactory) ;
try {
//子类覆盖方法做额外的处理
postProcessBeanFactory(beanFactory) ;
//激活各种BeanFactory 处理器
invokeBeanFactoryPostProcessors(beanFactory) ;
//注册拦截Bean 后置处理器, 这里只是注册,真正的调用是在getBean的时候
registerBeanPostProcessors(beanFactory);
//为上下文初始化Message 源, 即不同语言的消息体, 国际化处理
initMessageSource();
//初始化应用消息广播器, 并放入applicationEventMulticaster中
initApplicationEventMulticaster();
//留给子类来初始化其它的Bean
onRefresh();
//在所有注册的bean中查找Listenerbean ,注册到消息广播中
registerListeners();
//初始化剩下的单实例(非惰性的)
finishBeanFactoryinitialization(beanFactory);
//完成refresh,同时发出ContextRefreshEvent 通知别人
finishRefresh() ;
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex) ,
throw ex;
}
}
1、AbstractApplicationContext#prepareRefresh()
protected void prepareRefresh() {
// Switch to active. 记录上下文的启动时间
this.startupDate = System.currentTimeMillis();
//上下文是否关闭标志
this.closed.set(false);
//上下文是否活跃标志
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
//空方法,未做任何处理,正符合Spring 的开放式结构设计,给用户最大扩展Spring 的能力。
//用户可以根据自身的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及设置
initPropertySources();
getEnvironment().validateRequiredProperties();
//earlyApplicationListeners是刷新之前就会注册的本地监听器Set集合,applicationListeners是静态指定的监听器Set集合,
//当earlyApplicationListeners为空时,会初始化内容是applicationListeners;当earlyApplicationListeners不为空时,
//会将applicationListeners清空,内容再重置为earlyApplicationListeners。
if (this.earlyApplicationListeners == null) {
this.