美文网首页spring学习J2EE学习--Spring
Spring学习手册(6)—— bean生命周期管理

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

作者: 泽_渊 | 来源:发表于2017-03-16 11:21 被阅读80次

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

    一、实现方式

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

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

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

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

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

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

    <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
    
    public class ExampleBean {
    
        public void init() {
            // 执行相关的初始化操作
        }
    }
    

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

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

    <bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
    
    public class ExampleBean {
        public void cleanup() {
            // bean销毁时,做一些清理工作
        }
    }
    

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

    三、更近一步

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

    <beans default-init-method="init"  default-destroy-method="cleanup">
            
            <bean id="exampleInitBean" class="examples.ExampleBean" />
            <bean id="exampleInitBean2" class="examples.ExampleBean2" />
    </beans>
    
    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!");
        }
    }
    

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

    <?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-4.3.xsd"
           default-init-method="init" default-destroy-method="cleanup">
    
        <!-- 展示bean的调用顺序 -->
        <bean id="lifecycleExample1" class="com.liangwei.learnspring.LifecycleExample1">
            <property name="num" value="10"/>
        </bean>
        <!-- 全局配置方式-->
        <bean id="lifecycleExample2" class="com.liangwei.learnspring.LifecycleExample2"/>
    
        <!-- 本地配置方式 -->
        <bean id="lifecycleExample3" class="com.liangwei.learnspring.LifecycleExample3" init-method="anotherInit"/>
    </beans>
    

    请特别注意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生命周期管理

        本文链接:https://www.haomeiwen.com/subject/xwnrnttx.html