`

spring生命周期

 
阅读更多
http://sexycoding.iteye.com/blog/1046775

开篇先用一张老图描述下Spring中Bean容器的生命周期。


插叙一下,记得某个博文中提到:“Spring的Bean容器只管理非单例Bean的生命周期,单例Bean的生命周期不在管理范围内”,其实我认为这句话恰好说反了。首先明确一点,并非Spring容器中所有的Bean都有生命周期行为,只有接受容器管理生命周期的Bean才具有生命周期行为:而单例(Singleton)Bean接受容器管理,非单例(non-singleton)Bean在实例化后,完全交给了客户端代码管理,容器不再跟踪其生命周期,每次客户请求,容器都会创建一个新的实例,所以Spring容易无法知晓Bean何时销毁。

继续刚才的话题——Bean容器的生命周期。其实上图有个节点没有画出,就是在实例化所有Bean之前会执行BeanFactoryPostProcessors。不过也不care,因为这和Bean的生命周期没有太大关系,所以没有提及也属正常,权且忽略该节点。
从图中,我们可以看到实例化Bean的过程中有以下几个节点:
1)设置属性值;
2)调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;
3)调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口;
4)调用BeanPostProcessors.postProcessBeforeInitialization()方法;
5)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;
6)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)调用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果该Bean是单例的,则当容器销毁并且该Bean实现了DisposableBean接口的时候,调用destory方法;如果该Bean是prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。

好了,简单了描述了下那幅图。一切都还太抽象了,作为程序员,代码还是最直接的表达方式。那我们就一起看段演示代码吧。

首先,为达到演示效果,我们准备两个待测试的Bean,代码如下:
Java代码 
@Component 
public class DemoBean implements BeanFactoryAware, BeanNameAware, 
        InitializingBean, DisposableBean { 
    @PostConstruct 
    public void init() { 
       System.out.println("DemoBean: init-method"); 
    } 
    public void destroy() throws Exception { 
       System.out.println("DemoBean: destroy-method!"); 
    } 
    public void afterPropertiesSet() throws Exception { 
       System.out.println("DemoBean: after properties set!"); 
    } 
    public void setBeanName(String name) { 
       System.out.println("DemoBean: beanName aware, [name=" + name + "]"); 
    } 
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
       System.out.println("DemoBean: beanFactory aware, [beanFactory=" + beanFactory.toString() + "]"); 
    } 

 

Java代码 
public class AnotherDemoBean implements InitializingBean { 
  
    @PostConstruct 
    public void postConstruct() { 
       System.out.println("AnotherDemoBean: postConstruct-method"); 
    }   
    public void init() { 
       System.out.println("AnotherDemoBean: init-method"); 
    } 
    @Override 
    public void afterPropertiesSet() throws Exception { 
       System.out.println("AnotherDemoBean: after properties set!"); 
    } 


上面两个Bean大致相同,区别在于第一个Bean使用注解方式注入,第二个Bean我们使用配置文件方式,并指定其init-method,用于观察init-method与postConstruct的执行先后。

我们这个演示Bean实现了BeanFactoryAware, BeanNameAware, InitializingBean,  DisposableBean这几个接口,其实这些接口也可理解为Spring容器的一个个扩展点。

然后,我们再编写一个BeanPostProcessor,用于演示生命周期中的步骤4和步骤7。 代码如下:
Java代码 
@Component 
public class DemoBeanPostProcessor implements BeanPostProcessor { 
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
       System.out.println("DemoBeanPostProcessor: post process before initialization, [beanName=" + beanName + ", bean=" + bean + "]"); 
       return bean; 
    } 
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
       System.out.println("DemoBeanPostProcessor: post process before initialization, [beanName=" + beanName + ", bean=" + bean + "]"); 
       return bean; 
    } 

 
最后,我们编写测试类,以及Spring的配置文件,这里我们使用ClassPathXMLApplicationContext加载配置文件和初始化Spring容器。一起看下配置文件和测试类代码:
applicationContext.xml:
Xml代码 
<?xml version="1.0" encoding="GBK"?> 
  
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation=" 
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
    <context:component-scan base-package="com.shansun.multidemo"></context:component-scan> 
    <bean class="com.shansun.multidemo.spring.lifecycle.AnotherDemoBean" init-method="init"></bean> 
</beans> 
 
Main.java
Java代码 
public class Main { 
    @SuppressWarnings("unused") 
    public static void main(String[] args) { 
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
    } 

 
好了,一切就绪,我们就静观程序输出吧:
Java代码 
DemoBean: beanName aware, [name=demoBean] 
DemoBean: beanFactory aware, [beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@888e6c:defining beans [demoBean,demoBeanFactoryPostProcessor,demoBeanPostProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0]; root of factory hierarchy] 
DemoBean: init-method 
DemoBeanPostProcessor: post process before initialization, [beanName=demoBean, bean=com.shansun.multidemo.spring.lifecycle.DemoBean@1deeb40] 
DemoBean: after properties set! 
DemoBeanPostProcessor: post process before initialization, [beanName=demoBean, bean=com.shansun.multidemo.spring.lifecycle.DemoBean@1deeb40] 
AnotherDemoBean: postConstruct-method 
DemoBeanPostProcessor: post process before initialization, [beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0, bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean@1a7ddcf] 
AnotherDemoBean: after properties set! 
AnotherDemoBean: init-method 
DemoBeanPostProcessor: post process before initialization, [beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0, bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean@1a7ddcf] 
 
和我们预期的是否一样呢?是的。观察结果发现一个有趣的地方:在配置文件中指定的init-method和使用@PostConstruct注解的方法,孰先孰后呢,两者是否等同呢?后续我将通过分析源码给出结论。

我们通过演示代码也验证了Bean容器的生命周期,但是还缺点什么吧。对了,透过Spring源码讲述Bean容器的生命周期是否更加直观和令人信服呢?下面我们去Spring源码中一探究竟。这里我们选用的是spring-2.5.6.SEC02。

大家应该都知道Spring中BeanFactory和ApplicationContext的关系了吧,ApplicationContext继承自BeanFactory,所以可以操作到bean。更详细的内容可以参考许令波同学的《Spring框架的设计理念与设计模式分析》,里面有较清晰的分析。

好了,闲话不多说。

首先,我们探视下实例化Bean的方法initializeBean,该方法在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory类下,一起看下该段代码:
Java代码 
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { 
         if (bean instanceof BeanNameAware) { 
                   ((BeanNameAware) bean).setBeanName(beanName); 
         } 
  
         if (bean instanceof BeanClassLoaderAware) { 
                   ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); 
         } 
  
         if (bean instanceof BeanFactoryAware) { 
                   ((BeanFactoryAware) bean).setBeanFactory(this); 
         } 
  
         Object wrappedBean = bean; 
         if (mbd == null || !mbd.isSynthetic()) { 
                   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 
         } 
  
         try { 
                   invokeInitMethods(beanName, wrappedBean, mbd); 
         } 
         catch (Throwable ex) { 
                   throw new BeanCreationException( 
                                     (mbd != null ? mbd.getResourceDescription() : null), 
                                     beanName, "Invocation of init method failed", ex); 
         } 
  
         if (mbd == null || !mbd.isSynthetic()) { 
                   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 
         } 
         return wrappedBean; 

 
这样够直观了吧,是不是和前文描述的一样呢,J

本文源代码下载:https://lb-multi-demo.googlecode.com/svn/trunk/spring-lifecycle-test

By Mr.Chris
分享到:
评论

相关推荐

    Spring生命周期.png

    spring的创建详解图片,仅供参考

    Spring生命周期.vsdx

    Spring生命周期.vsdx

    Spring bean生命周期demo

    在Spring框架中,Bean的生命周期是指从创建到销毁的整个过程。这个过程包含了初始化、正常使用以及最终的销毁几个阶段。了解并掌握Spring Bean的生命周期对于优化应用性能和资源管理至关重要。接下来,我们将深入...

    spring bean的生命周期

    Spring Bean的生命周期是Spring框架中的核心概念,它涵盖了Bean从创建到销毁的全过程。了解这一过程对于优化应用程序的性能和管理资源至关重要。在Spring中,Bean的生命周期主要分为以下几个阶段: 1. **初始化阶段...

    第二十章 Spring 应用上下文生命周期(ApplicationContext Lifecycle)1

    这一节可能包含了对Spring生命周期相关面试题的解析,帮助读者更好地理解和准备面试。 15. **结束语** 总结全文,强调Spring应用上下文生命周期的重要性以及理解其工作原理对于开发和维护Spring应用的意义。 ...

    spring-lifecycle:一个用于试验 spring 生命周期的小示例应用程序

    标题中的"spring-lifecycle"暗示了这个项目专注于探索Spring框架中bean的生命周期管理。让我们深入了解一下Spring框架的生命周期及其相关的知识点。 在Spring中,bean的生命周期是指从创建到销毁的整个过程,它包括...

    spring bean的生命周期测试代码

    在Spring框架中,Bean的生命周期管理是其核心特性之一,它允许开发者控制Bean从创建到销毁的整个过程。本资源提供了在Spring 4.2环境下关于Bean生命周期的测试代码,帮助我们深入理解这一关键概念。 首先,让我们...

    Spring Bean生命周期.pdf

    其中,Spring Bean生命周期的管理是Spring框架的核心功能之一,它涉及Spring容器如何创建、配置以及销毁Bean的整个过程。理解Spring Bean的生命周期对于开发高效和可维护的Java应用至关重要。 Spring Bean生命周期...

    详解Spring中Bean的生命周期和作用域及实现方式

    Spring中Bean的生命周期和作用域及实现方式 Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了...

    spring bean life cycle

    在Spring框架中,Bean生命周期是核心概念之一,它涉及到Bean的创建、初始化、使用和销毁等阶段。了解和掌握Bean生命周期对于开发高质量的Spring应用至关重要。以下是对Spring Bean生命周期的详细解析。 首先,Bean...

    spring中service生命周期(xml/annotation)

    本文将探讨Spring中Service的生命周期,以及如何通过XML配置和注解来管理这些组件。 首先,Spring Service的生命周期通常包括实例化、初始化、正常运行、销毁四个阶段。在XML配置中,我们可以通过`&lt;bean&gt;`标签来...

    SpringBean的生命周期.mdj

    SpringBean的生命周期.mdj

    谈谈我对Spring Bean 生命周期的理解

    本文将详细介绍 Spring Bean 生命周期的概念、生命周期图、生命周期阶段、生命周期管理方式等相关知识点。 一、 Spring Bean 生命周期概述 Spring Bean 生命周期是指 Spring 容器中 Bean 的创建、初始化、销毁等...

    spring_in_action-sixth-edition.pdf

    Spring 生命周期是指 Spring 应用程序从启动到关闭的整个过程。Spring 生命周期包括应用程序的初始化、启动、运行和关闭等阶段。 11. Spring 配置 Spring 配置是指使用 Spring 框架的配置机制,帮助开发者快速构建...

    spring-hook-test.rar

    5. **Spring生命周期回调**:除了上述的`@PostConstruct`和`@PreDestroy`,Spring还提供了一些其他的生命周期回调,如`SmartLifecycle`接口,允许在应用启动和停止时控制Bean的启动和停止顺序。`@Application...

    Spring Bean 的生命周期

    本文主要介绍 Spring IoC 容器如何管理 Bean 的生命周期。 在应用开发中,常常需要执行一些特定的初始化工作,这些工作都是相对比较固定的,比如建立数据库连接,打开网络连接等,同时,在结束服务时,也有一些相对...

    架构师面试题系列之Spring面试专题及答案(41题).docx

    Spring 框架生命周期和 Bean 实例化过程 Spring 框架是一个非常流行的 Java Web 应用程序框架,它提供了一种灵活的方式来管理应用程序的生命周期。了解 Spring 的生命周期对于架构师和开发人员来说是非常重要的。 ...

Global site tag (gtag.js) - Google Analytics