Spring原理与源码分析系列(三)- Spring IoC容器启动过程分析(下)

本文深入分析了Spring IoC容器的启动过程,包括容器启动阶段和Bean实例化阶段。在启动阶段,容器加载配置信息,创建BeanDefinition并注册到BeanDefinitionRegistry。BeanFactoryPostProcessor接口允许在bean实例化前修改BeanDefinition。在Bean实例化阶段,容器会检查并实例化所需Bean,执行 Aware 接口、BeanPostProcessor、InitializingBean和destroy-method等生命周期方法。
摘要由CSDN通过智能技术生成

0 前言

关于Spring容器启动过程的分析,本章节文章分为两篇文章进行叙述,第一篇主要介绍Spring中Bean的相关概念以及IoC容器类型;第二篇开始详细介绍IoC容器的启动过程。
上篇Spring原理与源码分析系列(二)- Spring IoC容器启动过程分析(上)已经介绍了介绍Spring中Bean的相关概念以及IoC容器类型。本篇主要详述IoC容器的启动过程。

四、Spring IoC容器实现过程

Spring IoC容器实现过程可分为两个阶段:

  • 容器启动阶段
  • Bean实例化阶段

下面来详细解释这两个过程。

1 容器启动阶段

容器启动阶段,主要是对象管理信息的收集。
除了直接代码的方式,一般是先读取和加载配置信息内容,
并将分析后的信息编组为BeanDefinition,
然后将保存了bean定义必要信息的BeanDefinition注册到BeanDefinitionRegistry中,这样启动工作就完成了。
这里写图片描述
(第一阶段:容器启动阶段)

BeanFactoryPostProcessor
在容器启动阶段,BeanFactoryPostProcessor接口允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改,比如修改其中bean定义的某些属性,把bean的scope从singleton改为prototype,也可以把property的值给修改掉,为bean定义增加其他信息等。
BeanFactoryPostProcessor是在Spring容器加载了bean的定义文件之后,在bean实例化之前执行的。

BeanFactoryPostProcessor接口定义如下:

public interface BeanFactoryPostProcessor {

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息.

使用的时候,我们可以自己实现BeanFactoryPostProcessor接口,然后修改Bean属性。
举个栗子:
(1)Bean:

package com.wgs.spring.beanfactorypostprocessor;

/**
 * @author GenshenWang.nomico
 * @date 2017/11/21.
 */
public class Staff {
   
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

并为其注入属性值:

<bean id="staff" class="com.wgs.spring.beanfactorypostprocessor.Staff">
        <property name="age" value="25"></property>
        <property name="name" value="wgs"></property>
    </bean>

(2)自己实现一个BeanFactoryPostProcessor,将Bean属性中的name原始值“wgs”改为“Jack Ma”。

package com.wgs.spring.beanfactorypostprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author GenshenWang.nomico
 * @date 2017/11/21.
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
   


    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //BeanFactoryPostProcessor发生在读取Bean的BeanDefinition后,Bean实例化之前,所以获取的是BeanDefinition
        BeanDefinition staffBeanDefinition = beanFactory.getBeanDefinition("staff");
        //获取bean属性
        MutablePropertyValues propertyValues = staffBeanDefinition.getPropertyValues();
        if(propertyValues.contains("name")){
            propertyValues.addPropertyValue("name", "Jack Ma");
        }
    }
}

(3)测试:
注释掉spirng.xml中的配置:
<bean id="myBeanFactoryPostProcessor" class="com.wgs.spring.beanfactorypostprocessor.MyBeanFactoryPostProcessor"></bean>,输出的结果为”wgs”;

在spirng.xml加上<bean id="myBeanFactoryPostProcessor" class="com.wgs.spring.beanfactorypostprocessor.MyBeanFactoryPostProcessor"></bean>,这样BeanFactoryPostProcessor就能起作用,使name的值“wgs”被修改为“Jack Ma”,所以输出的结果也为“Jack Ma”。

如果一个容器有多个实现BeanFactoryPostProcessor的接口,这时候就需要实现类实现org.springframework.core.Ordered接口,设置order属性来保证自定义的BeanFactoryPostProcessor的实现类的执行顺序。

BeanFactoryPostProcessor接口有三个常用的实现类:
这里写图片描述

  • org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:允许我们在XML配置文件中使用占位符,并将这些占位符所代表的资源单独配置到简单的properties文件中来加载;
  • org.springframework.beans.factory.config.PropertyOverrideConfigurer:可以通过占位符,来明确表明bean定义中的property与properties文件中的各项配置项之间的关系。
  • org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器

BeanFactoryPostProcessor类图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值