SpringIOC容器它会以某种方式,加载配置文件中的 信息,将其解析为一个个的BeanDefinition.之后将BeanDefinition注册到容器之中。Spring IOC容器在实现的时候经过的过程可以使用如下图片表示:

分为两个主要部分:
其一 :容器启动阶段
其二:bean实例化阶段。

在容器的启动阶段主要做的是一些信息收集的过程(主要依赖于工具类BeanDefinitionReader),将收集的信息组成BeanDefinition.将BeanDefinition注册到相应的BeaneanRegistry.
Bean实例化的过程在请求方通过容器的getBean方法明确请求某个对象时候触发/隐式依赖关系调用时候也会触发该动作。此阶段做的操作主要是判断当前的请求对象是否已经被实例化过了。根据情况进行注入。当该对象实现某些回调接口。也会根据回调函数接口装配它

容器的前置处理 BeanFactoryPostProcess:

此后内容主要是对于容器实现第一阶段进行处理。Spring提供了容器扩展机制BeanFactoryPostProcess。这个机制允许我们在实例化相应对象之前对注册到容器中的BeanDefinition的存储信息进行修改。可以根据这个机制对Bean增加其它信息。修改Bean定义的某些属性值。
想自定义前置处理器需要实现BeanFactoryPostProcess接口。当一个容器存在多种前置处理的时候,可以让前置处理器的实现类同时继承Ordered接口。
Spring容器提供了数种现成的前置处理器,常见的如:

  • PropertyPlaceholderConfigurer:允许在xml文件中使用占位符。将占位符代表的资源单独配置到简单的Properties文件中加载
  • PropertyOverrideConfigurer:不同于PropertyPlaceholderConfigurer的是,该类用于处理容器中的默认值覆为新值的场景
  • CustomEditorConfigurer:此前的两个前置处理器处理的均是BeanDefinition.通过把BeanDefinition的数据修改达到目的。CustomEditorConfigurer没有对BeanDefinition做任何变动。负责的是将后期会用到的信息注册到容器之中。例如将类型转换器注册到BeanDefinition中。供BeanDefinition将获取到的String类型参数转换为需要的类型。

装配前置处理器

装配前置处理器分为两种情况。一种是普通的BeanFactory.一种是ApplicationContext.对于ApplicationContext可以自动识别并装配前置处理器。
ApplicationContext的装配可以直接用xml文件实现:
配置文件:

   <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>propertyHolder.properties</value></list></property></bean>

代码:

ApplicationContext factory=new ClassPathXmlApplicationContext("simple.xml");

启动的时候自动装载前置增强bean。无须额外操作。

BeanFactory装配方式:

     ConfigurableListableBeanFactory factory=new XmlBeanFactory(new ClassPathResource("simple.xml"));PropertyPlaceholderConfigurer configurer=new PropertyPlaceholderConfigurer();configurer.setLocation(new ClassPathResource("propertyHolder.properties"));configurer.postProcessBeanFactory(factory);

三种前置处理器

1.PropertyPlaceholderConfigurer前置处理器

应用场景:
不想将系统管理相关的业务配置信息混杂到XML文件中的时候,可以将文件配置到properties.如此可以在当系统参数发生变幻时候,只需修改properties配置文件。强化可读性的同时,也降低了维护难度。
代码:
配置文件

  <bean id="propertyHolder" class="com.example.demo.postprocess.MyPropertyHolderBean"><property name="username"><value>${java.version}</value></property><property name="password" value="${propertyHolder.password}"></property></bean>

bean包:

package com.example.demo.postprocess;public class MyPropertyHolderBean {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public void say() {System.out.println("username:"+username+";password:"+password);}
}

装配测试:

     ConfigurableListableBeanFactory factory=new XmlBeanFactory(new ClassPathResource("simple.xml"));PropertyPlaceholderConfigurer configurer=new PropertyPlaceholderConfigurer();configurer.setLocation(new ClassPathResource("propertyHolder.properties"));configurer.postProcessBeanFactory(factory);MyPropertyHolderBean bean=(MyPropertyHolderBean) factory.getBean("propertyHolder");bean.say();

分析:
对于PropertyPlaceholderConfigurer前置处理器的处理分步:

  • 创建xml文件装配需要使用前置增强装配的bean,使用占位符,占用value值
  • 创建properties文件,键值与xml中占位符名称一致
  • 通过beanFactory装载BeanDefinition
  • 创建PropertyPlaceholderConfigurer对象并把beanFactory作为入参,为beanFactory增加前置增强操作,替换BeanDefinition中的展位符

PropertyPlaceholderConfigurer前置增强不止会扫描装载的properties文件还会扫描System类下的属性。
PropertyPlaceholderConfigurer提供了三种默认的装载规则:

  • SYSTEM_PROPERTIES_MODE_FALLBACK :默认的装载规则。当properties中存在的时候使用properties中的值,不存在的时候则选择System中的值
  • SYSTEM_PROPERTIES_MODE_NEVER:从不扫描System中的值
  • SYSTEM_PROPERTIES_MODE_OVERRIDE:扫描系统值,当与properties中的值冲突时候,采用System中的值

当不设置的时候默认采用的是SYSTEM_PROPERTIES_MODE_FALLBACK。可以通过PropertyPlaceholderConfigurer对象的
setSystemPropertiesMode()方法或者setSystemPropertiesModeName() 方法,修改其扫描注入的规则。

本例子采用的BeanFactory方式进行测试,Application容器方式的方式装配起来更为简单。对于装配模式的设定可以在其bean定义的XML文件中使用注入的方式处理。

举例如:

        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>propertyHolder.properties</value></list></property><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"></property></bean>

其余的操作同正常的使用Application一样。十分简便。

2.PropertyOverrideConfigurer前置处理器

应用场景:
可以通过PropertyOverrideConfigurer对容器中任何想处理的bean定义中的信息进行覆盖替换。如此当容器创建bean的时候其bean的属性值就不同于xml文件的值了。
代码:
配置文件:

        <bean id="overrideBean" class="com.example.demo.postprocess.MyPropertyOverrideBean"><property name="username"><value>工具人</value></property><property name="password"><value>简单的密码</value></property></bean>

properties文件内容

overrideBean.username=\u6700\u65B0\u7684\u5DE5\u5177\u4EBA
overrideBean.password=\u6700\u65B0\u7684\u5BC6\u7801

测试用小Demo:

     ConfigurableListableBeanFactory factory=new XmlBeanFactory(new ClassPathResource("simple.xml"));PropertyOverrideConfigurer configurer=new PropertyOverrideConfigurer();configurer.setLocation(new ClassPathResource("propertyOverride.properties"));configurer.postProcessBeanFactory(factory);MyPropertyOverrideBean bean=(MyPropertyOverrideBean)factory.getBean("overrideBean");bean.say();

分析:
PropertyOverrideConfigurer的用法与PropertyPlaceholderConfigurer的使用方式类似。不同之处在于PropertyOverrideConfigurer的properties文件中的键值是bean名加其内部属性。而PropertyPlaceholderConfigurer的键值是其占位符的名。其次两者值注入的方式一种是替换占位符,一种是覆盖旧有的值。同时PropertyOverrideConfigurer不存在扫描System的情况。

Spring还可以支持对其加密的properties进行处理。PropertyOverrideConfigurerPropertyPlaceholderConfigurer均继承了PropertyResourceConfigurer,PropertyResourceConfigurer中提供了一个方法convertPropertyValue()方法,可以通过覆盖该方法对相应的配置项内容进行转换。

例子:

    <bean id="dealWithReplace" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"><property name="locations"><list><value>propertyOverride.properties</value></list></property><replaced-method name="convertPropertyValue" replacer="replaceMethod"></replaced-method></bean>

这里使用了方法替换的方式实现处理,使用继承的方式也可以,自行创建一个后置处理类,继承系统的后置处理类,之后重写其convertPropertValue()即可。在此不给具体代码了。
方法替换类:

public class MyReplacePostProcess implements MethodReplacer{@Overridepublic Object reimplement(Object obj, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stubreturn "对不起,"+obj.getClass().getSimpleName()+"的"+method.getName()+"被替换掉了";}}

其余的操作与之前例子一致,获得的结果是进行转换处理后的值。对于其Application的操作与PropertyPlaceholderConfigurer的类似在此也不加解释了。

3.CustomEditorConfigurer前置处理器

场景:
CustomEditorConfigurer与其余的两个前置处理器有所不同,它负责辅助性将后期会用到的信息注入到容器之中,本身对于BeanDefinition没有做任何变更
在使用配置文件配置参数的过程中会出现一种情况。配置文件中记载的数据都是String类型的,但是程序中的对象的类型却是多种多样的。想要完成这种转化,需要转化规则相关信息。CustomEditorConfigurer前置处理器负责的就是处理传递类型转换信息消息的一种前置处理器。

对于Spring内部使用PropertyEditor帮助我们把String转化为其它类型。每个对象类型对应一个的PropertyEditor.在做类型转换的过程中,采用默认JavaBean框架的PropertyEditor搜寻逻辑,继承对原生类型及Color,Font等类型的转化。
Sping还提供了部分的PropertyEditor:

  • StringArrayPropertyEditor. :此类型会将符合CSV格式的字符串转化为String[] 数组的形式,默认为以“,”分割的字符串。可以选择字符串的分割方式。ByteArrayPropertyEditor,CharArrayPropertyEditor均属于功能的PropertyEditor

  • ClassEditor:.根据String类型的class名称,将其转换为对应的class对象,效果与Class.forName(String)类似,入参可以是一个String[]数组,以数组形式传入的场合其作用与ClassArrayPropertyEditor一致

  • FileEditor :Spring提供的 对应 File文件类型的PropertyEditor。同属于对资源进行定位类型的还包括InputStreamEditor,URLEditor

  • LocaleEditor :针对Locale类型的PropertyEditor

  • PatternEditor:针对Pattern的PropertyEditor

以上的这些PropertyEditor容器默认会加载使用,即使不告诉容器如何对这些类型进行转换,容器依旧可以正确的进行转换工作。当我们需要转换的类型在以上PropertyEditor之外的场合。需要我们给出针对这种情况的自定义PropertyEditor,并且通过CustomEditorConfigurer告知容器,以让其可以实现正确的转化。

例子:
下面给出一个针对日期转换的PropertyEditor例子。对于Spring而言提供了个简便的实现自定义PropertyEditor的方法,通过实现PropertyEditor接口太复杂的情况下,可以通过继承PropertyEditorSupport类重写setAsText(String)来实现自定义。
PropertyEditor代码:

public class DatePropertyEditor extends PropertyEditorSupport {@Overridepublic void setAsText(String text) throws IllegalArgumentException {// TODO Auto-generated method stubSimpleDateFormat format=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");try {Date dateValue=format.parse(text);setValue(dateValue);} catch (ParseException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

xml配置文件:

  <bean id="dateEditor" class="com.example.demo.postprocess.DateEditorBean"><property name="date"><value>2019/1/1 11:11:11</value></property></bean>

测试用代码:

ConfigurableListableBeanFactory factory=new XmlBeanFactory(new ClassPathResource("simple.xml"));CustomEditorConfigurer configurer=new CustomEditorConfigurer();Map<Class<?>, Class<? extends PropertyEditor>> map=new HashMap();DatePropertyEditor editor= new DatePropertyEditor();map.put(java.util.Date.class,editor.getClass());configurer.setCustomEditors(map);configurer.postProcessBeanFactory(factory);DateEditorBean bean=(DateEditorBean)factory.getBean("dateEditor");System.out.println(bean.getDate());

分析:
本例子使用继承PropertyEditorSuppot自定义创建了一个字符串日期转换器。供给bean装配注入的时候使用。
具体操作方式分如下:

  • 继承PropertyEditorSupport,重写其setAsText()方法。将处理后的值通过setValue()的方式注入
  • 定义bean,同时使用setter注入方式注入值
  • 创建容器+前置处理器CustomEditorConfigurer对象,
  • 创建Map对象,将需要处理的类型的class与PropertyEditor对象的class对应上
  • 使用CustomEditorConfigurer对象的setCustomEditors()将PropertyEditor注册
  • 调用CustomEditorConfigurer对象的postProcessBeanFactory()告知容器前置处理的变更情况

至此容器前置增强内容结束,附上git代码地址:
github下载地址

Spring 的前置处理器介绍相关推荐

  1. Jmeter的元件使用介绍:前置处理器详解

    Jmeter的前置处理器可以用来在取样器执行前做一些数据准备操作,也需要注意使用的作用域问题.常用的前置处理器有:用户参数.BeanShell预处理器.JDBC预处理器. 一.用户参数 [用户参数]与 ...

  2. spring中的前置处理器和后置处理器区别

    背景: SpringIOC容器它会以某种方式,加载配置文件中的 信息,将其解析为一个个的BeanDefinition.之后将BeanDefinition注册到容器之中.Spring IOC容器在实现的 ...

  3. Spring Boot Actuator 使用介绍

    Spring Boot Actuator 使用介绍 初识 Actuator 原生端点 应用配置类 度量指标类 操作控制类 近期在看<Spring Cloud 微服务实战>,由于时间过去几年 ...

  4. Spring入门篇——第6章 Spring AOP的API介绍

    第6章 Spring AOP的API介绍 主要介绍Spring AOP中常用的API. 6-1 Spring AOP API的Pointcut.advice概念及应用 映射方法是sa开头的所有方法 如 ...

  5. 21天Jmeter打卡Day18 前置处理器_熟悉常用组件

    21天Jmeter打卡Day18 前置处理器_熟悉常用组件 https://www.jianshu.com/p/84866b2315f8 前置处理器使用场景 1.准备测试数据 2.数据加密–BeanS ...

  6. Jmeter前置处理器和后置处理器的使用

    JSON Extractor 如下发送请求后,此请求返回了一个json对象 点击下拉框选择json path tester,响应数据被格式化 如果要拿对象中的token就可以在下方输入token,并点 ...

  7. Spring中的IOC介绍

    Spring中的IOC介绍 IOC(控制反转) IOC介绍 IOC是什么 IOC能做什么 Spring容器管理对象 1.maven管理依赖 2.给定容器的配置文件 3.IOC容器管理对象 4.通过容器 ...

  8. 服务器sas卡的作用,英特尔IOP34x处理器介绍

    英特尔IOP34x处理器介绍 早在06年秋季的IDF大会上,英特尔就展示了新一代的IOP34x家族,可想而知IOP 33x家族更加久远.这代存储处理器整合了先进的数据保护.基于硬件的RAID 5/6( ...

  9. 我的Java Web之路 - Spring(1)- 介绍

    文章目录 介绍 建模 生产.装配/组装的思想 再谈容器 Spring工作模式 Spring的好处 总结 介绍 Spring在目前Java和Java Web开发里面简直就是神一样的存在,就是无处不在.这 ...

最新文章

  1. SAP MM ME21N 创建PO时报错 - Net price in CNY becomes too large – 之对策
  2. 使用CSS实现三栏自适应布局(两边宽度固定,中间自适应)
  3. Xcode Git 使用
  4. 基本的JVM内存分配过程案例
  5. Embeded linux之移植boa
  6. python填充_python 实现矩阵填充0的例子
  7. 自定义插入子串、删除子串、替换子串函数
  8. 把文档所有的字体都缩小一号_美观且专业的macOS字体管理工具
  9. Podfile 解析最佳实践
  10. 【梦幻西游】12门派版一键端
  11. axure rp8 添加动态面板_Axure原型教程:使用动态面板简单实现三级菜单
  12. 腾讯信鸽海量移动推送服务是如何构建的
  13. FMCW雷达测速和测距原理介绍
  14. 基于51单片机的俄罗斯方块游戏
  15. 扫雷php,扫雷php
  16. 互联网之于人类社会进化的意义
  17. 【解决办法】ES文件浏览器无法播放该链接
  18. 三菱 FX5U PLC结构化4轴伺服机器人程序
  19. 一刀工具箱 - 经纬度查询
  20. Sentinel限流

热门文章

  1. 关于高三经典励志文章精选
  2. 滴滴给自己留了后手。。。
  3. 日本都道府县的英文和日文对照(有序)
  4. iOS开发系列课程(01) --- iOS编程入门
  5. 为一台计算机配置Web服务器,DNS服务器与DHCP服务器
  6. 冰炭不投day博客导航
  7. 38 混沌和新生:区块链的流量生意|超级君【2019-12-02 2007】
  8. 隐写术,图片中隐藏的秘密!
  9. 使用python处理srec/s19文件
  10. 关于刷新网页F5,Ctrl+F5amp;amp;Shift+F5