Spring容器中的Bean几种初始化方法和销毁方法的先后顺序

原创 2013年03月03日 17:10:34

Spring 容器中的 Bean 是有生命周期的,Spring 允许 Bean 在初始化完成后以及销毁前执行特定的操作。下面是常用的三种指定特定操作的方法:

  • 通过实现InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
  • 通过<bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;
  • 在指定方法上加上@PostConstruct或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。

这几种配置方式,执行顺序是怎样的呢?我们通过例子来研究下:

Java类:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class InitAndDestroySeqBean implements InitializingBean,DisposableBean {

    public InitAndDestroySeqBean(){
        System.out.println("执行InitAndDestroySeqBean: 构造方法");
    }
    
    @PostConstruct
    public void postConstruct() {  
       System.out.println("执行InitAndDestroySeqBean: postConstruct");  
    }  
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("执行InitAndDestroySeqBean: afterPropertiesSet"); 
    }
    
    public void initMethod() {
        System.out.println("执行InitAndDestroySeqBean: init-method");
    }

    @PreDestroy
    public void preDestroy()  {
        System.out.println("执行InitAndDestroySeqBean: preDestroy");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("执行InitAndDestroySeqBean: destroy");
    }
    
    public void destroyMethod() {
        System.out.println("执行InitAndDestroySeqBean: destroy-method");
    }
    
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/chj/spring/bean.xml");
        context.close();
    }
}
Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:context="http://www.springframework.org/schema/context"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans  
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
 http://www.springframework.org/schema/context  
 http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
 
   <context:annotation-config/>  
   
   <bean id="initAndDestroySeqBean" class="com.chj.spring.InitAndDestroySeqBean" init-method="initMethod" destroy-method="destroyMethod"/>
</beans>
运行InitAndDestroySeqBean的main方法,结果如下:

2013-03-03 17:11:19,098 DEBUG support.DefaultListableBeanFactory - Creating instance of bean 'initAndDestroySeqBean'
执行InitAndDestroySeqBean: 构造方法
2013-03-03 17:11:19,114 DEBUG annotation.CommonAnnotationBeanPostProcessor - Found init method on class [com.alibaba.chj.spring.InitAndDestroySeqBean]: public void com.alibaba.chj.spring.InitAndDestroySeqBean.postConstruct()
2013-03-03 17:11:19,114 DEBUG annotation.CommonAnnotationBeanPostProcessor - Found destroy method on class [com.alibaba.chj.spring.InitAndDestroySeqBean]: public void com.alibaba.chj.spring.InitAndDestroySeqBean.preDestroy()
2013-03-03 17:11:19,129 DEBUG support.DefaultListableBeanFactory - Eagerly caching bean 'initAndDestroySeqBean' to allow for resolving potential circular references
2013-03-03 17:11:19,129 DEBUG annotation.CommonAnnotationBeanPostProcessor - Invoking init method on bean 'initAndDestroySeqBean': public void com.alibaba.chj.spring.InitAndDestroySeqBean.postConstruct()
执行InitAndDestroySeqBean: postConstruct
2013-03-03 17:11:19,129 DEBUG support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'initAndDestroySeqBean'
执行InitAndDestroySeqBean: afterPropertiesSet
2013-03-03 17:11:19,129 DEBUG support.DefaultListableBeanFactory - Invoking init method  'initMethod' on bean with name 'initAndDestroySeqBean'
执行InitAndDestroySeqBean: init-method
2013-03-03 17:11:19,129 DEBUG support.DefaultListableBeanFactory - Finished creating instance of bean 'initAndDestroySeqBean'
2013-03-03 17:11:19,129 INFO  support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@56a499: display name [org.springframework.context.support.ClassPathXmlApplicationContext@56a499]; startup date [Sun Mar 03 17:11:17 CST 2013]; root of context hierarchy
2013-03-03 17:11:19,129 INFO  support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1292d26: defining beans [org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,initAndDestroySeqBean]; root of factory hierarchy
2013-03-03 17:11:19,129 DEBUG annotation.CommonAnnotationBeanPostProcessor - Invoking destroy method on bean 'initAndDestroySeqBean': public void com.alibaba.chj.spring.InitAndDestroySeqBean.preDestroy()
执行InitAndDestroySeqBean: preDestroy
2013-03-03 17:11:19,145 DEBUG support.DisposableBeanAdapter - Invoking destroy() on bean with name 'initAndDestroySeqBean'
执行InitAndDestroySeqBean: destroy
2013-03-03 17:11:19,145 DEBUG support.DisposableBeanAdapter - Invoking destroy method 'destroyMethod' on bean with name 'initAndDestroySeqBean'
执行InitAndDestroySeqBean: destroy-method
从执行结果可以看出:

Bean在实例化的过程中:Constructor > @PostConstruct >InitializingBean > init-method

Bean在销毁的过程中:@PreDestroy > DisposableBean > destroy-method



spring的init-method的问题

Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。另外,如果bean是单例的...
  • u010263713
  • u010263713
  • 2014年03月16日 23:01
  • 5520

Spring 初始化Init和销毁Destory:

spring 容器对象的生命周期:         1、spring 容器创建对象         2、执行 init-method 方法         3、调用自己的方法         ...
  • hlbt0112
  • hlbt0112
  • 2015年10月03日 16:53
  • 1242

spring单例注入init

spring单例注入init
  • paincupid
  • paincupid
  • 2016年01月11日 16:33
  • 687

Spring Init Destory

public class testInitDestory { /*
  • qq_16103331
  • qq_16103331
  • 2016年09月27日 22:47
  • 171

Spring 的 init-method 和 destory-method

关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 ...
  • topwqp
  • topwqp
  • 2013年03月16日 16:32
  • 65177

Spring bean的生命周期init和destory

Bean生命周期:定义 --- 初始化 --- 使用 --- 销毁 一.初始化: 方法1.实现org.springframework.beans.foctory.InitializingBean接口...
  • sinat_32873711
  • sinat_32873711
  • 2016年12月16日 10:40
  • 970

Spring的init属性

今天在做项目的时候无意看到  在spring的配置中的根节点上有个  default-lazy-init="true"配置,从来没有用过,google下,记录如下 1、spring的default-...
  • liutong123987
  • liutong123987
  • 2016年01月12日 16:45
  • 268

spring 中bean初始化探究(一)–解析和注册bean definitaion

这两天在阅读spring的代码,为了提高学习效率,写了一个testcase,过程如下:1.写一个简单的java bean,这个bean只有一个属性,是Map类型,2:在spring中配置这个bean,...
  • Baple
  • Baple
  • 2015年04月02日 10:01
  • 993

spring initialize-database 使用方法

spring initialize-database 使用方法做系统时经常遇到需要初始化数据库的问题,spring 有个很用户的标签 initialize-database,实现这个功能,备忘下。只需...
  • xueba207
  • xueba207
  • 2015年12月29日 13:52
  • 941

spring中lazy-init详解

ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化(也就是依赖注入)。提前实例化意味着作为初始化过程的一部分,ApplicationCont...
  • fhx007
  • fhx007
  • 2011年11月27日 15:16
  • 45383
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
举报原因:
原因补充:

(最多只允许输入30个字)