1,Spring的两种IoC容器

BeanFactory

  • 基础类型的IoC容器;
  • 采用延迟初始化策略(容器初始化完成后并不会创建bean的对象,只有当收到初始化请求时才进行初始化);
  • 由于延迟初始化,因此启动速度较快,占用资源较少;

ApplicationContext

  • 在BeanFactory的基础上,增加了更为高级的特定:事件发布、国际化等;
  • 在容器启动时便完成所有bean的创建;
  • 启动时间较长,占用资源更多;

2,IoC容器的主要类/接口介绍

1)BeanFactory 
它是一个接口,提供了获取容器中Bean的相关方法。

2)BeanDefinitionRegistry 
它才是IoC的容器,用于存储、管理所有的Bean对象。

3)DefaultListableBeanFactory 
它是IoC容器的一个具体实现,实现了BeanFactory和BeanDefinitionRegistry接口,因此既拥有管理Bean的容器,又拥有访问Bean的方法。

4)BeanDefinition 
每一个Bean都有一个BeanDefinition与之对应,用于存储Bean的相关信息:对象的class类型、是否是抽象类、构造方法参数等。

RootBeanDefinitionChildBeanDefinition是BeanDefinition的两个主要的实现类。

5)BeanDefinitionReader 

在Spring中,标注Bean的依赖关系有四中方式:

    1. 直接在代码中声明
    2. 通过XML文件声明
    3. 通过Properties文件声明
    4. 通过注解声明 
      BeanDefinitionReader接口的作用就是读取配置文件中的bean信息,把它们解析成BeanDefinition对象,然后注册到BeanDefinitionRegistry中去。 
      PropertiesBeanDefinitionReader和XmlBeanDefinitionReader是该接口的两个实现类,分别用于解析properties和xml格式的配置文件。

6)XmlBeanFactory 
它是一个集成了XmlBeanDefinitionReader功能的BeanFactory,用于简化初始化操作。

3,BeanFactory的两个重要阶段

容器启动阶段

该阶段Spring会使用BeanDefinitionReader加载配置文件,并把所有的bean解析成BeanDefinition对象,并注册到BeanDefinitionRegistry

Bean实例化阶段

对于BeanFactory容器,当调用者主动调用getBean方法或者因存在依赖关系容器隐式调用getBean时,如果当前Bean尚未初始化,或者bean配置成prototype,就会触发Bean实例的初始化

4,BeanFactoryPostProcessor:一种容器扩展机制

Spring提供了BeanFactoryPostProcessor这种容器扩展机制,它允许我们在容器启动完成后Bean实例化前插入额外的操作

BeanFactoryPostProcessor提供了三个实现类:

1.PropertyPlaceholderConfigurer 
  一般情况下,我们并不会将数据库连接信息直接写死在dataSource这个bean中,而是将它们单独写在一个properties文件中,这样易于修改与阅读。而bean中使用占位符代替这些属性值,当容器启动完成后,在Bean初始化前用properties文件中的值替换占位符,再创建对象。 
PropertyPlaceholderConfigurer就能实现这样的功能。

  • xml中作如下配置:
<bean id="dataSource" class="xxxxxx">
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
</bean>
  • 使用properties文件存储属性值:
jdbc.url=jdbc:mysql://127.0.0.1:3306
jdbc.username=root

当容器启动完成后dataSource的BeanDefinition对象将会被注册进BeanDefinitionRegistry中,此时BeanDefinition中的属性值仍然是占位符的形式;接下俩,PropertyPlaceholderConfigurer就会发挥作用,它会将占位符用properties文件中的属性值替换掉。接下来bean就可以被正确地创建。

2.PropertyOverrideConfigurer 
它的功能与PropertyPlaceholderConfigurer类似,也需要指定一个properties文件,只不过它会用配置文件中设置的那些bean的属性值替换指定bean的属性值。

  • xml中作如下配置:
<bean id="dataSource" class="xxxxxx">
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306</value>
</property>
<property name="username">
<value>chai</value>
</property>
</bean>
  • 使用properties文件存储属性值:
dataSource.url=jsbc:mysql://127.0.0.1:3307
dataSource.username=root

PropertyOverrideConfigurer会在容器启动完毕后、Bean对象创建之前,通过修改BeanDefinition对象,替换指定的属性值。 
properties文件的内容必须遵循如下格式:

bean的名字.属性名=属性值

3.CustomEditorConfigurer 

该类用于向Spring容器增添自定义的PropertyEditor对象。

  容器启动结束后bean创建之前,配置文件中所有的bean都被解析成BeanDefinition对象,该对象中关于bean所有的信息都是String类型的,若要创建bean对象,就需要将这些String类型的信息解析成它们原本的类型。在Spring中,每种类型都有对应一个PropertyEditor类,该类中封装了String与该类型的转换方法。当然,对于某些类型Spring并未提供相应的PropertyEditor时,我们可以自定义PropertyEditor,并使用CustomEditorConfigurer将其告诉Spring容器,让它在遇到该类型的时候采用我们自定义的PropertyEditor去解析。

Spring提供的部分PropertyEditor:

    • StringArrayPropertyEditor 
      将字符串转换成String[],默认以,分割。
    • ClassEditor 
      类似于Class.forname(String),将字符串转换成class对象。
    • FileEditor 
      将字符串转换成File对象。
    • URLEditor 
      将字符串转换成URL对象。
    • InputStreamEditor 
      将字符串转换成InputStream对象。
    • LocaleEditor 
      将字符串转换成Locale对象。
    • PatternEditor 
      将字符串转换成Pattern对象。

以上类型的字符串,Spring会自动将它们转换成原本的类型。而我们自定义的PropertyEditor必须要通过CustomEditorConfigurer将其加入容器。

如何开启BeanFactoryPostProcessor功能? 
1.BeanFactory

// 创建BeanFactory对象
ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory( new ClassPathResource("xxx") );
// 创建BeanFactoryPostProcessor对象
PropertyPlaceholderConfigurer processor = new PropertyPlaceholderConfigurer();
// 设置properties文件的位置
processor.setLocation("xxx");
// 将其传递给beanFactory
processor.postProcessBeanFactory(beanFactory);

2.ApplicationContext 
ApplicationContext会自动检测配置文件中出现的BeanFactoryPostProcessor,因此只需要在配置文件中声明所使用的BeanFactoryPostProcessor即可。

<bean class="xxxxx.PropertyPlaceholderConfigurer">
<property>
<list>
<value>properties文件路径</value>
</list>
</property>
</bean>

https://blog.csdn.net/u010425776/article/details/55269888

Spring IoC容器实现的更多相关文章

  1. Spring IoC容器的初始化过程

    Spring IoC容器的初始化包括 BeanDefinition的Resource定位.载入和注册 这三个基本的过程.IoC容器的初始化过程不包含Bean依赖注入的实现.Bean依赖的注入一般会发生 ...

  2. 【Spring】非Spring IOC容器下获取Spring IOC上下文的环境

    前言 在Spring Web项目中,有些特殊的时候需要在非Spring IOC容器下获取Spring IOC容器的上下文环境,比如获取某个bean. 版本说明 声明POM文件,指定需引入的JAR. & ...

  3. 学习Spring(一) 实例化Spring IoC容器

    实例化Spring IoC容器 1,读取其配置来创建bean实例 2,然后从Spring IoC容器中得到可用的bean实例 Spring提供两种IoC容器实现类型 a,一种为bean工厂 b,应用程 ...

  4. MyEclipse Spring 学习总结一 Spring IOC容器

    一.Spring IOC容器---- Spring AllicationContext容器 程序的结构如下: 1.首先在MyEclipse 创建创建Java Project 2.创建好后,添加spin ...

  5. 对Spring IoC容器实现的结构分析

    本文的目标:从实现的角度来认识SpringIoC容器. 观察的角度:从外部接口,内部实现,组成部分,执行过程四个方面来认识SpringIoC容器. 本文的风格:首先列出SpringIoC的外部接口及内 ...

  6. spring IOC容器实例化Bean的方式与RequestContextListener应用

    spring IOC容器实例化Bean的方式有: singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时, ...

  7. 解读Spring Ioc容器设计图

    在Spring Ioc容器的设计中,有俩个主要的容器系列:一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器最基本的功能:另外一个是ApplicationContext应用上下 ...

  8. 纯注解快速使用spring IOC容器

    使用spring的ioc容器实现对bean的管理与基本的依赖注入是再经典的应用了.基础使用不在详述. 这里主要介绍下使用注解实现零配置的spring容器.我相信你也会更喜欢使用这种方式.Spring ...

  9. Spring IOC容器分析(2) -- BeanDefinition

    上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefin ...

  10. Spring IOC容器分析(4) -- bean创建获取完整流程

    上节探讨了Spring IOC容器中getBean方法,下面我们将自行编写测试用例,深入跟踪分析bean对象创建过程. 测试环境创建 测试示例代码如下: package org.springframe ...

随机推荐

  1. SpringBoot 对静态资源的映射规则

    一.所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源 webjars:以jar包的方式引入静态资源,如下:引入 jquery ...

  2. [SharePoint2010开发入门经典]8集成业务线数据,使用业务联通服务

    本章概要: 1.了解office business application 2.理解商务联通服务(BCS),如何使用BCS构建OBA 3.通过BCS使用SharePoint和办公集成技术

  3. HDU 2138

    这题用MILLER测试应该是不可避免的. #include <iostream> #include <cstdio> #include <stdlib.h> #in ...

  4. 使用SecueCRT在本地主机与远程主机之间交互文件

    名词解释 本地主机:执行SecueCRT,以管理远程Linux或Unix的机器(一般为Windows系统) 远程主机:被SecueCRT进行管理控制的机器(一般为Linux或Unix) 1.开启SFT ...

  5. 经验之谈—OAuth授权流程图

    事实上我们在开发中,常常须要解决获得用户的一些特定的数据,比方:能够选择使用微博登陆.使用QQ登陆等等.然后我们间接的获得用户的头像.昵称等信息.这些都涉及到OAuth授权的内容 OAuth授权有这么 ...

  6. VS2015--win32project配置的一些想法之在 Visual Studio 2015 中进行调试的同一时候分析性能

    出处: https://msdn.microsoft.com/zh-cn/magazine/dn973013(en-us).aspx 很多开发商花了绝大多数时间获取应用程序才干正常发挥作用.更少的时间 ...

  7. React中多行文本省略不生效原因

    在普通的前端项目中,在不考虑兼容问题的时候,可以用以下代码实现: overflow : hidden; text-overflow: ellipsis; display: -webkit-box; - ...

  8. linux的chmod,chown命令 详解

    指令名称 : chmod 使用权限 : 所有使用者 使用方式 : chmod [-cfvR] [--help] [--version] mode file... 说明 : Linux/Unix 的档案 ...

  9. Nosql的实际应用场景

    怎么样把NoSQL引入到我们的系统架构设计中,需要根据我们系统的业务场景来分析,什么样类型的数据适合存储在NoSQL数据库中,什么样类型的数据必须使用关系数据库存储.明确引入的NoSQL数据库带给系统 ...

  10. ES6的基本语法

    ES6 详细参考页面 简介 ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现.一般来说,这两个词是可以互换的. let命令 ES6新增了let命令,用来声明变 ...