[Spring]浅谈ApplicationContext

1.ApplicationContext概述

Spring对ApplicationContext的解释为:

BeanFactroy提供了容器的配置机制,可以管理任何类型的对象,而ApplicationContext扩展自BeanFactory,在此基础上,它增加了Spring AOP、国际化、事件发布等功能。

BeanFactory是面向框架本身的,而ApplicationContext是更加侧重于面向企业应用,可以说ApplicationContext是BeanFactory的超集。

2. UML

UML

3. ApplicationContext

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

可以看到,ApplicationContext分别扩展了EnvironmentCapableListableBeanFactoryHierarchicalBeanFactoryMessageSourceApplicationEventPublisherResourcePatternResolver,关于ListableBeanFactoryHierarchicalBeanFactory这里就不重复介绍了,今天介绍一下剩余的几个接口:

  • EnvironmentCapable

这里做一个小插曲:capable->能力,以后看到某个接口包含了Capable,可以理解为声明某某能力的意思。
提供访问应用程序运行环境的能力,主要对profiles和properties建模。

profiles是一个概要文件,你可以在程序中@Profile来指定当前程序处于什么状态,通常在企业开发中,profile代表不同的运行环境:dev、test、prod等

properties是更为重要的角色,它的来源可以来自:properties files、JVM系统属性、环境变量、JNDI、servlet上下文属性等

  • MessageSource

解析消息的策略类,支持消息的参数化和国际化,

  • ApplicationEventPublisher

事件发布,应用了观察者模式

  • ResourcePatternResolver

加载资源文件,支持ant的路径规则,例如常见的一些资源文件:"/WEB-INF/*-context.xml",继承自ResourceLoader,关于ResourceLoader,这里不做详细介绍,它是一个解析资源的策略类,根据不同的策略加载不同的资源。

4. 容器实现类

4.1 ApplicationContext概览

ApplicationContext声明的方法都是只读性的。

ApplicationContext

4.2 Lifecycle

用来控制Bean/容器本身的生命周期

4.3 ConfigurableApplicationContext概览

Spring为了让容器具备可配置化,声明了ConfigurableApplicationContext的扩展接口,
该接口提供了对ApplicationContext的写方法:

ConfigurableApplicationContext

不仅如此,它还声明了模板方法refresh,控制上下文的close

4.4 常见实现

  • FileSystemXmlApplicationContext:独立XML应用程序上下文,从文件系统或URL中获取上下文定义文件,将纯路径解释为相对文件系统位置.
  • ClassPathXmlApplicationContext:默认从classPath进行资源加载.
  • XmlWebApplicationContext:Web容器,从xml中获取配置,加载XmlBeanDefinition,默认情况下,从"/WEB-INF/applicationContext.xml"获取上下文配置。SSM项目中经常用到
  • AnnotationConfigWebApplicationContext:基于注解的Web应用容器

5. 基于XML和注解的容器不同之处

xml的容器是基于xml配置来解析BeanDefinition的,而基于注解的则要指定一个启动类,配置组件扫描。

6. refresh

refresh是所有容器都需要实现的方法。Spring用ConfigurableApplicationContext声明了refresh方法,在抽象类AbstractApplicationContext中声明了模板方法refresh。该方法包含:

  • prepareRefresh:准备此上下文以进行刷新,设置其启动日期和活动标志以及执行属性源的任何初始化。
  • obtainFreshBeanFactory:通知子类启动refreshBeanFactory,子类必须实现refreshBeanFactory
  • prepareBeanFactory:从Spring容器获取BeanFactory(Spring Bean容器)并进行相关的设置为后续的使用做准备,例如:ClassLoader
  • postProcessBeanFactory:允许子类注册特殊的BeanPostProcessors,钩子方法
  • invokeBeanFactoryPostProcessors:激活在容器中注册为bean的工厂处理器。
  • registerBeanPostProcessors:注册Bean创建的后置处理器
  • initMessageSource:初始化国际化配置
  • initApplicationEventMulticaster:在Spring容器中初始化事件广播器,事件广播器用于事件的发布。
  • onRefresh:设置内置的Web容器,如:Tomcat、Jetty、Undertow
  • registerListeners:把Spring容器内的时间监听器和BeanFactory中的时间监听器都添加的事件广播器中。
  • finishBeanFactoryInitialization:实例化BeanFactory中已经被注册但是未实例化的所有实例(懒加载的不需要实例化)
  • finishRefresh:发布相应的事件,例如: ContextRefreshedEvent.
    protected void finishRefresh() {
        // Clear context-level resource caches (such as ASM metadata from scanning).
        clearResourceCaches();

        // Initialize lifecycle processor for this context.
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }

refresh是一个模板方法的应用,子类可以重写上述的12个方法中的abstract方法,进行不同行为的表达,最后容器就会调用refresh加载不同实现类的方法。

总结

ApplicationContext在BeanFactory的基础上继续扩展,提供了应用级别的能力声明,其主要能力在AbstractApplicationContext得以体现,包括:系统资源管理、资源解析、事件发布、国际化、容器初始化和前后置处理器的支持、容器生命周期管理等等。
不仅如此,从庞大的类结构你可以看到,Spring包含了很多设计原则:单一职责、开闭原则、面向接口原则等等。正是这种大师级别的容器实现,才能让Spring Framework可以兼容灵活性、扩展性。
最后,放一张对比图,从中概览BeanFactory和ApplicationContext的区别:

Feature Matrix

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容