spring & spring mvc 初始化介绍

spring & spring mvc 初始化介绍

web项目的结构

java servlet 技术

java servlet 技术是 java 的一个 web 服务规范, 提供了统一的 servlet api 供各个容器厂商实现, 以保证一个 java web 项目可以运行在不同厂商的服务器下.

请看实例简单复习下 servlet, listner, filter

listner, filter 会在 web 容器启动时执行 init 方法

servlet 会在第一次访问时进行初始化. 当然也可以设置 init on start

非 servlet 规范的 java web 项目

使用netty作为服务器lib, 加入 http 协议的处理层, 自行完成处理 http 请求读写

spring mvc 的的封装

我们最常用到的 spring mvc 框架就是对 servlet 技术的封装, 在 web.xml 中加入实现 ListennerSpringContextListener 和实现了 ServletDispatcherServlet, 来对spring 和 spring mvc 进行初始化.

spring context 结构

spring context 是整个 spring 的核心, 通常也被叫做 spring 容器. 通常讲的 spring 初始化过程, 就是初始化 spring context 的过程.

根据应用不同, 使用的 spring context 类型也不同

继承树

context继承.png

常见的 war 包形式的 web 应用, 使用的是 XmlWebApplicationContext

spring boot 默认使用的是 AnnotationConfigEmbeddedWebApplicationContext

重要组件

  • BeanFactory 通用组件, 负责 bean 注册和初始化
  • Environment 通用组件 , 包含系统参数, 启动参数等. 还有对启动参数解析后的属性, 比如 profile
  • ApplicationListeners 通用组件, 保存注册进来的context事件listener
  • 一些 context 状态标志, parent
  • ServletContext, ServletConfig WebApplicationContext类里特有的
  • 一些特定的参数. 在特定context类型中, 比如
/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; 

spring context 初始化过程概念概览

一个 spring context 的初始化过程大致分为以下几个阶段:

  1. 读取并设置系统参数, 环境变量, 获取一些初始化 context 需要的组件, 比如 ApplicationContextInitializer 等.

    这个属于context 初始化的前置逻辑, 由应用自己控制, 我们也可自己来写, 用来给后面 context 初始化做准备

    这一步根据应用不同差别很大, 比如传统 war 包的 ContextLoadListner 和 spring boot 的 SpringApplication 中的逻辑就很不同.

  2. create context

    根据应用不通, 创建不同的 context

  3. configure context

    用第1步获得的参数和组件, 来配置创建好的 context

  4. context.refresh

    核心步骤, context 初始化的具体过程就在这里.

    包括分门别类的加载各种特殊的 bean, 然后加载普通的ben

spring 初始化过程实例概览(非 spring boot 的传统war包)

ContextLoaderListener

ContextLoaderListener 配置在 web.xml 中, 在容器启动时初始化.

ContextLoaderListener.png

部分较为重要步骤解释:

    1. 决定spring web app context类型. 不指定的情况下默认策略创建 XmlWebApplicationContext
    1. 以 bean 的 configuration 文件, 就是一般我们说的xml文件 为入口, 加载 BeanDefinition 到 bean factory. 注意仅仅是加载 bean 的描述, 而没有实例化这些 bean
    1. 实例化执行所有的 BeanFactoryPostProcessor, 从 BeanDefinition 中和 context 的 beanFactoryPostProcessors 字段中查找.
  • BeanFactoryPostProcessor是意图在 bean factory 加载了所有定义的 bean 定义之后, 且在这些 bean 实例化之前, 做一些操作.

    这一步通常在调用各个 processor 时, 产生新的 bean 定义到 bean factory

    1. 注册 BeanPostProcessor , 从 BeanDefinition 中查找.
  • BeanPostProcessor 会在之后每个 bean 实例化之后调用, 用来对 bean 做一些其他操作, 比如放入一些参数:

    AutowiredAnnotationBeanPostProcessor 的作用就是注入 @Autowired 字段.

    生成动态代理对象也是通过 BeanPostProcessor 实现的.

    1. onRefresh 是用来初始化其他的特殊的 bean, 这部分逻辑通常在特殊的 context 子类实现

    比如在 spring boot 中使用的 AnnotationConfigEmbeddedWebApplicationContext 中, 会在这里初始化并启动内嵌服务器

    1. 将在 BeanDefinition 中的, 还有之前设置到context属性中的 ApplicationListener 加到广播列表中
    1. BeanDefinition 中其他的非懒加载的 bean 实例化.
    1. 实例化并调用 LifecycleProcessor , 然后广播 ContextRefreshedEvent
    1. 将 context 放到 ServletContext 的 attribute 属性里, 之后 DispatcherServlet 初始化会用到

*以上说的 bean 均为 singleton 的 scope

DispatcherServlet

DispatcherServlet 配置在 web.xml 中, 在第一次访问时初始化.

DispatcherServlet.png

部分较为重要步骤解释:

    1. ContextLoaderListener创建的 context 为 parent, 创建新的 XmlWebApplicationContext
    1. 创建一个 ContextRefreshListener , 加入到 context 中, 监听 ContextRefreshedEvent
    1. refresh 过程跟ContextLoaderListener 一样, 不同的是在查找 bean 时, 能够查到 parent context 的 bean, 供新的 context 初始化使用.
    1. 触发 ContextRefreshedEvent , 初始化 spring mvc 的组件, 添加到 DispatcherServlet 中.

一些特殊类型Bean的初始化时机 (待完善, 请持续补充)

BeanFactoryPostProccesor

context refresh 之后, 初始化好 factory 之后, 会先执行 context 自身的 factory post 操作, 然后就会执行 BeanFactoryPostProccesor 这种类型 bean 所定义的 factory post 操作.

BeanDefinitionRegistryPostProcessor

BeanFactoryPostProccesor 的子类, 执行优先级比 BeanFactoryPostProccesor 要高. 通常可以通过 order 来控制BeanDefinitionRegistryPostProcessor 类型的执行顺序, 还跟这个 bean 定义的时机有关, 在 prepare context 阶段定义的总会最先执行.

通常自定义的 xml 和 bean 配置 会在这个阶段被定义到 factory.

BeanPostProccesor

BeanFactoryPostProccesor 都执行完之后实例化, 并 apply 到 factory , 在一个 bean 初始化之后会被调用.

Aware

ApplicationContextAware , 实现这个接口的 bean 会由一个 BeanPostProccesor 类型的 ApplicationContextAwareProcessor 在初始化之后 set 一个 application context

Aware 相关类的很多, 都类似

ApplicationListener

用来监听 context 生命周期中各个事件的类, 可以在 prepare 和 refresh 阶段注入

ApplicationContextInitializer

prepare context 阶段执行, 在 context refresh之前执行. 可以对 context 注入 BeanFactoryPostProccesorApplicationListener

交流

欢迎加入群 661035226,gradle,spring,activiti 交流

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,736评论 6 342
  • Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相...
    Theriseof阅读 2,795评论 1 24
  • 什么是Spring Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Jav...
    jemmm阅读 16,439评论 1 133
  • “你大学过的真是……没成绩、没恋爱、没回忆、没文化。过得没心没肺,倒是真的。”这是昨天晚上和一个学长聊天,他给我下...
    大了学那点事阅读 232评论 1 1