一、Spring 容器高层视图

Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配号Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。

二、内部工作机制

该图描述了Spring容器从加载配置文件到创建出一个完整Bean的作业流程:

1、ResourceLoader从存储介质中加载Spring配置信息,并使用Resource表示这个配置文件的资源;

2、BeanDefinitionReader读取Resource所指向的配置文件资源,然后解析配置文件。配置文件中每一个<bean>解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中;

3、容器扫描BeanDefinitionRegistry中的BeanDefinition,使用Java的反射机制自动识别出Bean工厂后处理后器(实现BeanFactoryPostProcessor接口)的Bean,然后调用这些Bean工厂后处理器对BeanDefinitionRegistry中的BeanDefinition进行加工处理。主要完成以下两项工作:

1)对使用到占位符的<bean>元素标签进行解析,得到最终的配置值,这意味对一些半成品式的BeanDefinition对象进行加工处理并得到成品的BeanDefinition对象;

2)对BeanDefinitionRegistry中的BeanDefinition进行扫描,通过Java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean),并自动将它们注册到Spring容器的属性编辑器注册表中(PropertyEditorRegistry);

4.Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手进行Bean实例化的工作;

5.在实例化Bean时,Spring容器使用BeanWrapper对Bean进行封装,BeanWrapper提供了很多以Java反射机制操作Bean的方法,它将结合该Bean的BeanDefinition以及容器中属性编辑器,完成Bean属性的设置工作;

6.利用容器中注册的Bean后处理器(实现BeanPostProcessor接口的Bean)对已经完成属性设置工作的Bean进行后续加工,直接装配出一个准备就绪的Bean。

Spring容器确实堪称一部设计精密的机器,其内部拥有众多的组件和装置。Spring的高明之处在于,它使用众多接口描绘出了所有装置的蓝图,构建好Spring的骨架,继而通过继承体系层层推演,不断丰富,最终让Spring成为有血有肉的完整的框架。所以查看Spring框架的源码时,有两条清晰可见的脉络:

1)接口层描述了容器的重要组件及组件间的协作关系;

2)继承体系逐步实现组件的各项功能。

接口层清晰地勾勒出Spring框架的高层功能,框架脉络呼之欲出。有了接口层抽象的描述后,不但Spring自己可以提供具体的实现,任何第三方组织也可以提供不同实现, 可以说Spring完善的接口层使框架的扩展性得到了很好的保证。纵向继承体系的逐步扩展,分步骤地实现框架的功能,这种实现方案保证了框架功能不会堆积在某些类的身上,造成过重的代码逻辑负载,框架的复杂度被完美地分解开了。

Spring组件按其所承担的角色可以划分为两类:

1)物料组件:Resource、BeanDefinition、PropertyEditor以及最终的Bean等,它们是加工流程中被加工、被消费的组件,就像流水线上被加工的物料;

2)加工设备组件:ResourceLoader、BeanDefinitionReader、BeanFactoryPostProcessor、InstantiationStrategy以及BeanWrapper等组件像是流水线上不同环节的加工设备,对物料组件进行加工处理。

摘录于《Spring 3.x 企业应用实战》

Spring容器初始化过程的更多相关文章

  1. Spring源码-IOC部分-容器初始化过程【2】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  2. spring容器初始化执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  3. 当spring 容器初始化完成后执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  4. 当spring 容器初始化完成后执行某个方法 防止onApplicationEvent方法被执行两次

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  5. spring容器初始化bean和销毁bean之前进行一些操作的定义方法

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:        第一种,通过在xml中定义init-method和destory-method方法        第二种, ...

  6. Spring IoC容器初始化过程学习

    IoC容器是什么?IoC文英全称Inversion of Control,即控制反转,我么可以这么理解IoC容器: 把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为I ...

  7. spring源码学习之路---深度分析IOC容器初始化过程(四)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近由于工作和生活,学习耽搁 ...

  8. Spring之IOC容器初始化过程

    Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动. 具体来说这个启动过程包括三个基本过程: 1.BeanDifinition的Resource定位 2.Bean ...

  9. Spring源码解析二:IOC容器初始化过程详解

    IOC容器初始化分为三个步骤,分别是: 1.Resource定位,即BeanDefinition的资源定位. 2.BeanDefinition的载入 3.向IOC容器注册BeanDefinition ...

随机推荐

  1. Xcode 6 正式版如何创建一个Empty Application

    Xcode 6 正式版里面没有Empty Application这个模板,这对于习惯了纯代码编写UI界面的程序员来说很不习惯. 有网友给出了一个解决方法是,把Xcode 6 beta版里面的模板复制过 ...

  2. do{...}while(0)的意义和用法

    linux内核和其他一些开源的代码中,经常会遇到这样的代码: do{ ... }) 这样的代码一看就不是一个循环,do..while表面上在这里一点意义都没有,那么为什么要这么用呢? 实际上,do{. ...

  3. C# 非托管内存使用时的注意事项

    调用Marshal.AllocHGlobal必须调用 Marshal.FreeHGlobal(ptr)来手动释放内存,即使调用GC.Collect();方法也无法释放,导致内存泄露!!

  4. PDF.js

    http://www.linuxidc.com/Linux/2015-06/118728.htm http://blog.csdn.net/xiangcns/article/details/42089 ...

  5. 如何在maven中添加本地jar包

    mvn install:install-file -DgroupId=mytest-DartifactId=test-Dversion=1.1 -Dpackaging=jar -Dfile=d:\te ...

  6. C# Winfrom 页面传值

    2个窗体 Parent,Children 代码: Parent public partial class Parent : Form { public string parentValue = &qu ...

  7. 手动设置Windows7锁屏界面背景

    windows7系统安装之后锁屏.关机界面.开机欢迎界面都是系统默认的背景,其实这些背景就像桌面壁纸一样是可以更改的,如果没有修改过的话,按下面步骤就可以修改了. 首先选择一张喜欢的背景图片,分辨率不 ...

  8. ACM/ICPC 之 最短路-SPFA+正逆邻接表(POJ1511(ZOJ2008))

    求单源最短路到其余各点,然后返回源点的总最短路长,以构造邻接表的方法不同分为两种解法. POJ1511(ZOJ2008)-Invitation Cards 改变构造邻接表的方法后,分为两种解法 解法一 ...

  9. Python~list,tuple^_^dict,set

    tuple~(小括号) list~[中括号] 和list比较,dict有以下几个特点: dict~{‘key’:value,} set~set([1,2,3]) tuple一旦初始化就不能修改~指向不 ...

  10. 跨浏览器的事件对象-------EventUtil 中的方法及用法

    什么是EventUti----封装好的事件对象 在JavaScript中,DOM0级.DOM2级与旧版本IE(8-)为对象添加事件的方法不同 为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即 ...