Spring学习手册(6)—— bean生命周期管理

Spring学习手册(5)——bean作用域我们学习了Spring为我们提供的bean的几类声明周期声明,我们重点学习了singletonprototype两种声明。本文我们将学习如何与IOC容器的bean生命周期管理进行交互。

一、实现方式

当我们需要在bean初始化和销毁时执行特定的动作时,Spring为我们提供了两个不同的方式来实现:

  • bean继承InitializingBean�DisposableBean接口。接口InitializingBeanafterPropertiesSet()会在属性设置方法调用完成后调用;接口DisposableBeandestroy()方法会在bean销毁时(超出作用域)执行;
  • 使用XML配置的方式:其中标签的init-method属性可制定该bean的初始化方法,destroy-method属性可指定bean的销毁方法。效果与集成接口方式一致。

为了简化学习成本并且减少代码与Spring框架的耦合,这里我们主要讲解演示XML配置方式的使用。

Tip : 除以上方法外,Spring还提供了注解的方式来声明初始化方法和销毁方法,如:@PostConstruct@PreDestroy,这里也不做进一步讲述。

二、初始化方法和销毁方法配制

当我们需要bean在初始化完成后执行相关动作时,我们可以使用Spring提供的XML配置方式来指定代码类的相应方法为初始化方法。样式如下:


public class ExampleBean {

    public void init() {
        // 执行相关的初始化操作
    }
}

如上所示,在XML配置文件中我们使用init-method属性指定该bean的public void init()方法为初始化方法。该方法要求返回值为void且无参,除此之外,名字可任意更改,只需要保证bean所指定的类中包含此方法。

同样,我们可以如下简单的配置销毁方法:


public class ExampleBean {
    public void cleanup() {
        // bean销毁时,做一些清理工作
    }
}

和初始化方式相似,我们使用destroy-method方法指定销毁时的清理方法,上面的例子中指向public void cleanup(),该方法同样也是返回值为void且无参,其中方法名可任意更改。

三、更近一步

当我们需要为大量的bean配置初始化方法和销毁清理方法时,Spring也为我们提供了更高效的方式:在beans标签里使用default-init-methoddefault-destroy-method属性,同时我们需要让我们的所有bean只需要定义相同的初始化方法签名和销毁清理方法签名。
代码样式如下:


        
        
        

public class ExampleBean {
    
    public void init(){
      //执行相关的初始化操作
    }
    public void cleanup() {
        // bean销毁时,做一些清理工作
    }
}
public class ExampleBean2 {
    
    public void init(){
      //执行相关的初始化操作
    }
    public void cleanup() {
        // bean销毁时,做一些清理工作
    }
}

如上配置方式,我们对ExampleBeanExampleBean2完成了初始化操作方法和销毁清理方法,其中特别重要的时所有bean的初始化方法和销毁方法必须一致:一般我们使用public void init()方法签名来定义初始化方法。

Tip: 当我们需要为某一个bean设置特殊的初始化方法或销毁清理方法是,我们只需要在具体的bean定义标签里使用init-method属性指定,它会覆盖全局设置。

四、代码示例

示例代码构造了主要使用三个类来进行演示,主要展示一下功能:

类名 展示功能
LifecycleExample1 展示各方法的调用顺序
LifecycleExample2 演示全局配置方式效果
LifecycleExample3 演示特殊bean配置覆盖全局配置

代码构造如下:

LifecycleExample1.java

public class LifecycleExample1 {

    private int num;

    public LifecycleExample1() {
        System.out.println("LifecycleExample1 constructed!");
    }

    public void setNum(int num) {
        this.num = num;
        System.out.println("LifecycleExample1 setNum method called!");
    }

    public void init(){
        System.out.println("LifecycleExample1 init method called!");
    }

    public void cleanup(){
        System.out.println("LifecycleExample1 cleanup method called!");
    }
}

LifecycleExample2.java

public class LifecycleExample2 {

    public void init(){
        System.out.println("LifecycleExample2 init method called!");
    }

    public void cleanup(){
        System.out.println("LifecycleExample2 cleanup method called!");
    }
}

LifecycleExample3.java

public class LifecycleExample3 {

    public void anotherInit(){
        System.out.println("LifecycleExample3 anotherInit method called1");
    }

    public void init(){
        System.out.println("LifecycleExample3 init method called!");
    }
}

以上代码简单就不做过多赘述。
配置方式如下:




    
    
        
    
    
    

    
    

请特别注意default-init-methoddefault-destroy-method属性的使用以及lifecycleExample3配置中init-method属性的使用。

Application.java
为了使Spring能调用我们的配置的销毁清理方法,我们需要IOC容器注册一个JVM关闭的钩子(hook),如下所示:

public class Application {

    public static void main(String[] args){


        ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");

        applicationContext.registerShutdownHook();
    }
}

运行代码控制台显示信息如下:

LifecycleExample1 constructed!
LifecycleExample1 setNum method called!
LifecycleExample1 init method called!
LifecycleExample2 init method called!
LifecycleExample3 anotherInit method called1
LifecycleExample2 cleanup method called!
LifecycleExample1 cleanup method called!

通过输出信息我们可以总结:

  • 初始化方法会在seter方法调用完成后被IOC容器调用;
  • 当配置全局default-init-methoddefault-destroy-method后,该配置文件下的所有bean如果有该方法会在合适时机被调用;
  • 当使用init-methoddestroy-method对全局配置进行覆盖时,即使该bean有全局配置的方法也不会被调用,而是只调用最新配置的方法。

五、总结

本文我们讲述了如何在bean完成初始化或销毁时执行指定的动作。通过该方式我们就可以灵活的进行一些操作:系统启动时预加载缓存,提高执行效率;系统启动时初始化数据库连接等......

本文源代码下载

你可能感兴趣的:(Spring学习手册(6)—— bean生命周期管理)