spring bean的生命周期

1. Spring Bean的生命周期简介

Spring bean 的生命周期是指 Bean 在 Spring(IoC)中从创建到销毁的整个过程。

在Spring框架中,Bean的生命周期包括以下阶段:

  1. 实例化:通过构造函数或工厂方法创建Bean实例。
  2. 属性赋值:调用Bean实例的setter方法将属性值注入到Bean中。
  3. 初始化:执行Bean实例的初始化方法,例如init-method指定的方法。
  4. 使用:Bean实例被放入容器中供其他对象使用。
  5. 销毁:容器关闭时,销毁Bean实例,执行Bean实例的destroy-method指定的方法。

Spring框架提供了各种扩展点,使得用户可以对Bean的生命周期进行自定义处理,例如通过BeanPostProcessor接口来拓展初始化前后的操作,通过DisposableBean接口来定义销毁方法等。下面我们从这些扩展点入手,详细介绍Spring Bean的生命周期。

2. Spring Bean的实例化

Bean的实例化是指根据Bean定义创建一个实例对象的过程。具体来说,Bean的实例化分为以下两个阶段:

  1. BeanDefinition的加载和解析:在启动Spring容器时,容器会读取应用程序上下文配置文件或通过Java代码配置的BeanDefinition,并将其解析成spring内部数据结构,这些数据结构描述了Bean的元数据信息,如:类名、属性、依赖关系等信息。
  2. 实例化Bean对象:解析完成后,Spring容器使用Java反射机制创建Bean对象并初始化它们,同时注入所需的依赖项和属性值。通常情况下,Spring通过调用Bean的无参构造函数来创建实例对象。如果Bean的构造函数需要参数,则Spring将根据参数类型自动查找并注入所需的依赖项。

需要注意的是,在默认情况下,Spring使用单例模式创建Bean实例。也就是说,每个Bean定义只对应一个实例对象,所有从容器中获取该Bean的请求都将返回同一个实例。如果需要创建多个实例,可以通过配置作用域(scope)来实现

在实例化阶段,开发者还可以通过实现BeanPostProcessor接口的回调方法在Bean实例化前后进行一些自定义操作,例如修改Bean属性值、记录日志等。

关于spring bean的配置文件,通常使用XML配置,也可以使用java的@Configuration和@Bean注解。

Spring框架提供了三种方式来实例化Bean:

2.1 使用构造函数实例化Bean

使用构造函数实例化Bean是最常见的方式。在XML配置文件中,我们可以使用标签来指定构造函数的参数值。例如:

<bean id="myBean" class="my.package.MyBean">
    <constructor-arg name="arg1" value="value1"/>
    <constructor-arg name="arg2" ref="refBean"/>
</bean>

在这个例子中,我们通过标签来指定了MyBean的构造函数需要两个参数,一个是value1,另一个是refBean这个Bean实例。

2.2 使用静态工厂方法实例化Bean

使用静态工厂方法实例化Bean需要在XML配置文件中指定factory-method属性和factory-bean属性。例如:

<bean id="myBean" class="my.package.MyBeanFactory" factory-method="createBean">
    <constructor-arg name="arg1" value="value1"/>
    <constructor-arg name="arg2" ref="refBean"/>
</bean>

在这个例子中,我们指定了MyBeanFactory类中的createBean静态方法来实例化Bean,并且通过标签来指定createBean方法需要的参数值。

2.3 使用实例工厂方法实例化Bean

使用实例工厂方法实例化Bean需要在XML配置文件中指定factory-method属性和factory-bean属性。不同的是,factory-bean属性需要指向一个已经存在于容器中的Bean实例,而不是一个类名。例如:

<bean id="myBeanFactory" class="my.package.MyBeanFactory"/>
 
<bean id="myBean" factory-bean="myBeanFactory" factory-method="createBean">
    <constructor-arg name="arg1" value="value1"/>
    <constructor-arg name="arg2" ref="refBean"/>
</bean>

在这个例子中,我们指定了MyBeanFactory类中的createBean方法来实例化Bean,并且通过factory-bean属性指定了MyBeanFactory类的实例。

3. Spring Bean的属性赋值

在Spring框架中,我们可以使用setter方法、构造函数来对Bean的属性进行赋值。其中,setter方法是最常用的方式。例如:

<bean id="myBean" class="my.package.MyBean">
    <property name="prop1" value="value1"/>
    <property name="prop2" ref="refBean"/>
</bean>

在这个例子中,我们通过标签来指定了MyBean需要注入的两个属性:prop1和prop2。其中,prop1的值为value1,prop2的值为refBean这个Bean实例。

如果我们需要对一个List或Map等集合类型的属性进行赋值,可以使用标签。例如:

<bean id="myBean" class="my.package.MyBean">
    <property name="listProp">
    <list>
        <value>value1</value>
        <value>value2</value>
    </list>
    </property>
    <property name="mapProp">
       <map>
        <entry key="key1" value="value1"/>
        <entry key="key2" value="value2"/>  
        </map>
    </property>
</bean>

在这个例子中,我们使用标签来分别指定了MyBean中的listProp和mapProp属性需要赋值的内容。

4. Spring Bean的初始化

Spring框架提供了两种方式来执行Bean的初始化方法:

4.1 使用init-method指定初始化方法

可以在XML配置文件中使用init-method属性来指定Bean的初始化方法。例如:

<bean id="myBean" class="my.package.MyBean" init-method="init">
    <property name="prop1" value="value1"/>
    <property name="prop2" ref="refBean"/>
</bean>

在这个例子中,我们通过init-method属性指定了MyBean的初始化方法为init。

4.2 实现InitializingBean接口

还可以让Bean实现InitializingBean接口,并重写afterPropertiesSet()方法。例如:

public class MyBean implements InitializingBean {
 
    private String prop1;
    private RefBean prop2;
 
    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化操作
    }
 
    // setter和getter方法省略
 
}

在这个例子中,我们让MyBean类实现了InitializingBean接口,并在afterPropertiesSet()方法中编写了初始化操作。

5. Spring Bean的使用

一旦Bean被实例化、属性赋值并初始化后,它就可以被放入容器中供其他对象使用了。例如:

<bean id="myService" class="my.package.MyService">
    <property name="myBean" ref="myBean"/>
</bean>

在这个例子中,我们将MyBean注入到了MyService中的myBean属性中,并且将MyService放入了容器中供其他对象使用。

6. Spring Bean的销毁

在Spring框架中,我们可以使用destroy-method属性来指定Bean的销毁方法。例如:

<bean id="myBean" class="my.package.MyBean" destroy-method="destroy">
    <property name="prop1" value="value1"/>
    <property name="prop2" ref="refBean"/>
</bean>

在这个例子中,我们通过destroy-method属性指定了MyBean的销毁方法为destroy。

还可以让Bean实现DisposableBean接口,并重写destroy()方法。例如:

public class MyBean implements DisposableBean {
 
    private String prop1;
    private RefBean prop2;
 
    @Override
    public void destroy() throws Exception {
        // 销毁操作
    }
 
    // setter和getter方法省略
 
}

在这个例子中,我们让MyBean类实现了DisposableBean接口,并在destroy()方法中编写了销毁操作。

7. Spring Bean的扩展点

除了上述介绍的Bean生命周期阶段,Spring框架还提供了各种扩展点,使得用户可以对Bean的生命周期进行自定义处理。

7.1 BeanPostProcessor接口

BeanPostProcessor接口定义了两个方法:postProcessBeforeInitialization()和postProcessAfterInitialization(),分别在Bean实例化和初始化前后执行。用户可以通过继承该接口并实现这两个方法来拓展Bean的初始化前后操作。

public class MyPostProcessor implements BeanPostProcessor {
 
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 初始化前操作
        return bean;
    }
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 初始化后操作
        return bean;
    }
 
}

在这个例子中,我们实现了BeanPostProcessor接口,并在postProcessBeforeInitialization()和postProcessAfterInitialization()方法中

CT

posted @ 2023-05-19 10:23  路迢迢  阅读(204)  评论(0编辑  收藏  举报