Spring Bean 生命周期



  • Bean 生命周期

    Spring bean的生命周期很容易理解。实例化Bean时,可能需要执行一些初始化以使其进入可用状态。同样,当不再需要bean并将其从容器中删除时,可能需要进行一些清理。尽管在bean实例化和销毁之间有一些活动在后台进行,但本章将仅讨论两个重要的bean生命周期回调方法,这些方法在bean初始化及其销毁时是必需的。要定义bean的设置和拆卸,我们只需使用init-methoddestroy-method参数声明 。init-method属性指定在实例化后立即在Bean上调用的方法。同样,destroy-method指定一种在将bean从容器中删除之前被调用的方法。
  • 初始化回调

    org.springframework.beans.factory.InitializingBean接口指定一个方法
    void afterPropertiesSet() throws Exception;
    
    因此,您可以简单地实现上述接口,并且可以在afterPropertiesSet()方法内部完成初始化工作,如下所示:
    public class ExampleBean implements InitializingBean {
       public void afterPropertiesSet() {
          // 做一些初始化工作
       }
    }
    
    对于基于XML的配置元数据,可以使用init-method属性指定具有无返回值无参数签名的方法的名称。例如
    <bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
    
    以下是类定义
    public class ExampleBean {
       public void init() {
          // 做一些初始化工作
       }
    }
    
  • 销毁回调

    org.springframework.beans.factory.DisposableBean接口指定一个方法
    void destroy() throws Exception;
    
    因此,您可以简单地实现上述接口,并且可以在destroy()方法内部完成销毁工作,如下所示:
    public class ExampleBean implements DisposableBean {
       public void destroy() {
          // 做一些销毁工作
       }
    }
    
    对于基于XML的配置元数据,可以使用destroy-method属性指定具有无返回值无参数签名的方法的名称。例如
    <bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
    
    以下是类定义
    public class ExampleBean {
       public void destroy() {
          // 做一些销毁工作
       }
    }
    
    如果您在非Web应用程序环境中使用Spring的IoC容器;例如,在客户端桌面环境中,您向JVM注册了一个关闭钩子。这样做可以确保正常关闭,并在您的单例 bean上调用相关的destroy方法,以便释放所有资源。建议不要使用InitializingBeanDisposableBean回调,因为XML配置在命名方法方面具有很大的灵活性。
  • 实例

    假设我们拥有一个运行良好的Eclipse IDE,并采取以下步骤来创建一个Spring应用程序:
    1. 创建一个名称为SpringExample的项目,并在创建的项目的src文件夹下创建一个包com.jc2182
    2. 使用“添加外部JAR”选项添加所需的Spring库,如“Spring Hello World示例”一章中所述。
    3. 在com.jc2182包下创建Java类HelloWorld和MainApp。
    4. 在src文件夹下创建Beans配置文件Beans.xml。
    5. 最后一步是创建所有Java文件和Bean配置文件的内容,然后按以下说明运行应用程序。
    这是HelloWorld.java文件的内容:
    package com.jc2182;
    
    public class HelloWorld {
       private String message;
    
       public void setMessage(String message){
          this.message = message;
       }
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
       public void init(){
          System.out.println("Bean is going through init.");
       }
       public void destroy() {
          System.out.println("Bean will destroy now.");
       }
    }
    
    以下是MainApp.java文件的内容:在这里,您需要注册一个在AbstractApplicationContext类上声明的关闭钩子registerShutdownHook()方法。这将确保正常关闭并调用相关的destroy方法。
    package com.jc2182;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
    
          HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
          obj.getMessage();
          context.registerShutdownHook();  // 注册关闭钩子方法 ,确保正常关闭得以调用相关的销毁方法
       }
    }
    
    以下是初始化和销毁​​方法所需的配置文件Beans.xml
    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.jc2182.HelloWorld" init-method = "init" 
          destroy-method = "destroy">
          <property name = "message" value = "Hello World!"/>
       </bean>
    
    </beans>
    
    完成创建源和Bean配置文件后,让我们运行该应用程序。如果您的应用程序一切正常,它将显示以下消息:
    Bean is going through init.
    Your Message : Hello World!
    Bean will destroy now.
    
  • 默认的初始化和销毁​​方法

    如果您有太多具有相同名称的初始化和/或销毁方法的bean,则无需在每个单独的bean上声明init-methoddestroy-method。相反,该框架提供了灵活性,可以使用<beans>元素上的0default-init-methoddefault-destroy-method属性配置这种情况,如下所示-
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
       default-init-method = "init" 
       default-destroy-method = "destroy">
    
       <bean id = "..." class = "...">
          <!-- collaborators and configuration for this bean go here -->
       </bean>
       
    </beans>