扩展spring容器

springIoc容器它会以某种方式加载ConfigMetadata(通常就是XML格式的配置信息或是注解),然后根据信息绑定整个系统的对象,最终组装成一个可用的基于轻量级容器的应用系统。spring的IOC容器实现以上功能的过程,基本上可以按照类似的流程分为两个阶段,即容器启动阶段和Bean实例化阶段。spring的IOC容器在实现的时候,充分运用了这个两个实现阶段的不同特点,在每个阶段加入了相应的容器扩展点,以便我们可以根据具体场景的需要加入自定义的扩展逻辑。

  • spring提供了一种叫做BeanFactoryPostProcessor的容器扩展机制,该机制允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改。这就相当于在容器实现的第一阶段最后加入一道工序,让我们对最终的BeanDefinition做一些额外的操作,比如修改其中bean定义的某些属性,为bean等一增加其它信息等
  • PropertyPlaceholderConfigurer允许我们在XML配置文件中使用占位符(PlaceHolder),并将这些占位符所代表的资源单独配置到简单的properties文件中来加载。这些都是很常见的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="clone">
    <!-- 基本属性driverClassName、 url、user、password -->
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${account.jdbc.url}" />
    <property name="username" value="${account.jdbc.username}" />
    <property name="password" value="${account.jdbc.password}" />

    <!-- 配置初始化大小、最小、最大 -->
    <!-- 通常来说,只需要修改initialSize、minIdle、maxActive -->
    <!-- 初始化时建立物理连接的个数,缺省值为0 -->
    <property name="initialSize" value="2" />
    <!-- 最小连接池数量 -->
    <property name="minIdle" value="2" />
    <!-- 最大连接池数量,缺省值为8 -->
    <property name="maxActive" value="10" />

    </bean>
1
2
3
4
jdbc.url=jdbc\:mysql\://192.168.4.201\:3306/test?useUnicode\=true&characterEncoding\=utf-8&allowMultiQueries\=true
jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.jdbc.Driver

基本机制:当BeanFactory在第一阶段加载完成所有配置信息时,BeanFactory中保存的对象的属性信息还只是以占位符的形式存在,如${jdbc.url}。当PropertyPlaceholderConfigurer被作为BeanFactoryPostProcessor应用时,它会使用properties配置文件中的配置信息来替换相应BeanDefinition中占位符表示的属性值。