Spring总结_06_bean的生命周期

1.生命周期流程图

上下文ApplicationContext容器中的生命周期:

英文图解:

中文图解:

Spring Bean的生命周期具体流程:

1.Bean容器找到配置文件中Spring Bean的定义。
       2.Bean容器利用Java Reflection API创建一个Bean的实例。
       3.如果涉及到一些属性值 利用set方法设置一些属性值。
       4.如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。
       5.如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
       6.如果Bean实现了BeanFactoryAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
       7.与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。
       8.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法
       9.如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
       10.如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。
       11.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessAfterInitialization()方法
       12.当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。
       13.当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。

二.各种接口方法分类

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

1、Bean自身的方法         :这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

2、Bean级生命周期接口方法 :这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

4、工厂后处理器接口方法   :这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的

工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

三.接口方法介绍

1. Aware接口   (Bean级)

(1)ApplicationContextAware: 获得ApplicationContext对象,可以用来获取所有Bean definition的名字。

(2)BeanFactoryAware         : 获得BeanFactory对象,可以用来检测Bean的作用域。

(3)BeanNameAware           : 获得Bean在配置文件中定义的名字。

(4)ResourceLoaderAware   : 获得ResourceLoader对象,可以获得classpath中某个文件。

(5)ServletContextAware    : 在一个MVC应用中可以获取ServletContext对象,可以读取context中的参数。

(6)ServletConfigAware      : 在一个MVC应用中可以获取ServletConfig对象,可以读取config中的参数。

Aware接口是针对某个实现这些接口的Bean定制初始化的过程,几个xxxAware接口的作用类似,暂以 BeanNameAware接口为例:

BeanNameAware接口

此接口用于获得Bean在配置文件中定义的名字:Spring Bean存活于容器之中,一般情况下spring bean对context的情况并不了解,如果希望某个bean知道自己在

context中的代号:bean name(一个bean在容器中的id),即可让该bean的类型实现BeanNameAware接口。

示例:

applicationContext.xml

<bean id="javaLanguage" class="org.test.spittr.spi.LanguageBean">
    <property name="languageName" value="Java"/>
</bean>

实体bean

package org.test.spittr.spi;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;/

public class LanguageBean implements BeanNameAware {
    private String languageName;
    private String beanName;

    public LanguageBean() {    }

    public String getLanguageName() {
        return languageName;
    }

    public void setLanguageName(String languageName) {
        this.languageName = languageName;
    }

    public void setBeanName(String s) {
        this.beanName = s;
    }

    public String getBeanName() {
        return beanName;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(this.getClass().getName());
        if(this.getBeanName() != null) {
            sb.append(": name \‘").append(this.getBeanName()).append("\‘");
        } else {
            sb.append(": unnamed");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        Resource resource = new FileSystemResource("/Users/duqi/Downloads/Spittr/src/main/resources/bean-life.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        LanguageBean languageBean = (LanguageBean) beanFactory.getBean("javaLanguage");
        System.out.println(languageBean.getLanguageName());
        System.out.println(languageBean.getBeanName());
        System.out.println(languageBean.toString());
    }
}

运行结果:

Java
javaLanguage
org.test.spittr.spi.LanguageBean: name ‘javaLanguage‘

2. BeanPostProcessor接口(容器级)

(1)如果说上述几个xxxAware接口的作用是定制单个bean的初始化过程,那么BeanPostProcessor接口则可以提供全局的、定制多个bean的初始化过程,只需提供一个实现BeanPostProcessor接口的类即可。

(2)该接口中包含两个方法,postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法会在容器中的Bean初始化(属性值设置)之前执行, postProcessAfterInitialization方法在容器中的Bean初始化之后执行。

示例:

applicationContext.xml

<bean class="com.giraffe.spring.service.CustomerBeanPostProcessor"/>

实体类

public class CustomerBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行BeanPostProcessor的postProcessBeforeInitialization方法,beanName=" + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行BeanPostProcessor的postProcessAfterInitialization方法,beanName=" + beanName);
        return bean;
    }

}

3. InitializingBean接口   和   DisposableBean接口(Bean级)

这两个接口都只包含一个方法。通过实现InitializingBean接口的afterPropertiesSet()方法可以在Bean属性值设置好之后做一些操作,实现DisposableBean接口的destroy()方法可以在销毁Bean之前做一些操作。

在bean的声明周期中,afterPropertiesSet()方法的调用介于postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法之间。

在实际项目中,可以考虑按照如下模式使用InitializingBean接口:

public class GiraffeService implements InitializingBean,DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("执行InitializingBean接口的afterPropertiesSet方法");

    }

    @Override
    public void destroy() throws Exception {
        System.out.println("执行DisposableBean接口的destroy方法");
    }
}

这种方法比较简单,但是不建议使用。因为这样会将Bean的实现和Spring框架耦合在一起。

时间: 2024-10-08 18:07:54

Spring总结_06_bean的生命周期的相关文章

Spring中Bean的生命周期

Spring中Bean的生命周期过程: 1.Spring对Bean进行实例化(相当于程序中的new Xx()) 2.Spring将值和Bean的引用注入进Bean对应的属性中 3如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法 (实现BeanNameAware清主要是为了通过Bean的引用来获得Bean的ID,一般业务中是很少有在Bean的ID的) 4.如果Bean实现了BeanFactoryAware接口,Spring将调用se

Spring的Bean的生命周期以及Bean的后置处理器

Bean的生命周期: Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务. Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1通过构造器或工厂方法创建 Bean 实例 2为 Bean 的属性设置值和对其他 Bean 的引用 3调用 Bean 的初始化方法(可以人为指定,利用Bean标签的inti-method属性指定初始化方法,不指定就默认忽略这步骤) Bean 可以使用了 4当容器关闭时, 调用 Bea

spring之bean的生命周期

上篇文章中,详细介绍了spring中bean的scope,scope既是bean在spring容器中的存在方式,如prototype和singleton,且也带了一些存在周期的属性,如 session和request等.spring中 bean从实例化,到依赖注入.再到初始化.到最后消亡,有和完整的生命周期.它和scope一起构成bean完整的生命周期.本篇文章主要简单的描述下bean生命周期中的初始化方法(init())和消亡前(ondestroy(),以后称之为析构)的方法.本文主要讨论sc

JAVA面试题:Spring中bean的生命周期

Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一实例,对单线程的程序说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程同时存取共享资源所引发的数据不同步问题. 然而在spring中 可以设定每次从BeanFactory或Appl

spring(二、bean生命周期、用到的设计模式、常用注解)

Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring容器.这里,我们讲的也是 ApplicationContext中Bean的生命周期.而实际上BeanFactory也是差不多的,只不过处理器需要手动注册.  转载 http://www.cnblogs.com/zrtqsk/p/3735273.html 一.生命周期流程图: Spring Bean的

Spring:Spring中bean的生命周期

Spring中,从BeanFactory或ApplicationContext取得的实例为Singleton(单例模式),就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一实例,对单线程的程序说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程同时存取共享资源所引发的数据不同步问题. 然而在spring中 可以设定每次从BeanFactory或ApplicationContext指定别名并

深究Spring中Bean的生命周期

一.Bean 的完整生命周期 在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了.一旦bean不再被使用,则由Java自动进行垃圾回收. 相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程 Bean 的生命周期 如上图所示,Bean 的生命周期还是比较复杂的,下面来对上图每一个步骤做文字描述:

深入剖析Spring(三)——Bean的生命周期

对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收.而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制.Spring中每个Bean的生命周期如下: 1. 实例化Bean 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化. 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean. 容器通

Spring中Bean的生命周期方法

Bean的生命周期方法 src\dayday\Car.java package dayday; import com.sun.org.apache.xpath.internal.SourceTree; import javax.sound.midi.Soundbank; /** * Created by I am master on 2016/11/28. */public class Car { private String name; public void setName(String n