欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Bean的生命周期详细介绍

程序员文章站 2024-03-13 13:36:33
spring作为当前java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解spring bean的生命周期是非常必要的。我们通常使用applicationc...

spring作为当前java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解spring bean的生命周期是非常必要的。我们通常使用applicationcontext作为spring容器。这里,我们讲的也是 applicationcontext中bean的生命周期。而实际上beanfactory也是差不多的,只不过处理器需要手动注册。

一、生命周期流程图:

  spring bean的完整生命周期从创建spring容器开始,直到最终spring容器销毁bean,这其中包含了一系列关键点。

 Spring Bean的生命周期详细介绍

若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。

二、各种接口方法分类

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

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

2、bean级生命周期接口方法  :  这个包括了beannameaware、beanfactoryaware、initializingbean和diposablebean这些接口的方法

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

4、工厂后处理器接口方法  :  这个包括了aspectjweavingenabler, configurationclasspostprocessor, customautowireconfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。  

三、演示

我们用一个简单的spring bean来演示一下spring bean的生命周期。

1、首先是一个简单的spring bean,调用bean自身的方法和bean级生命周期接口方法,为了方便演示,它实现了beannameaware、beanfactoryaware、initializingbean和diposablebean这4个接口,同时有2个方法,对应配置文件中<bean>的init-method和destroy-method。如下:

package springbeantest;

import org.springframework.beans.beansexception;
import org.springframework.beans.factory.beanfactory;
import org.springframework.beans.factory.beanfactoryaware;
import org.springframework.beans.factory.beannameaware;
import org.springframework.beans.factory.disposablebean;
import org.springframework.beans.factory.initializingbean;

/**
 * @author qsk
 */
public class person implements beanfactoryaware, beannameaware,
    initializingbean, disposablebean {

  private string name;
  private string address;
  private int phone;

  private beanfactory beanfactory;
  private string beanname;

  public person() {
    system.out.println("【构造器】调用person的构造器实例化");
  }

  public string getname() {
    return name;
  }

  public void setname(string name) {
    system.out.println("【注入属性】注入属性name");
    this.name = name;
  }

  public string getaddress() {
    return address;
  }

  public void setaddress(string address) {
    system.out.println("【注入属性】注入属性address");
    this.address = address;
  }

  public int getphone() {
    return phone;
  }

  public void setphone(int phone) {
    system.out.println("【注入属性】注入属性phone");
    this.phone = phone;
  }

  @override
  public string tostring() {
    return "person [address=" + address + ", name=" + name + ", phone="
        + phone + "]";
  }

  // 这是beanfactoryaware接口方法
  @override
  public void setbeanfactory(beanfactory arg0) throws beansexception {
    system.out
        .println("【beanfactoryaware接口】调用beanfactoryaware.setbeanfactory()");
    this.beanfactory = arg0;
  }

  // 这是beannameaware接口方法
  @override
  public void setbeanname(string arg0) {
    system.out.println("【beannameaware接口】调用beannameaware.setbeanname()");
    this.beanname = arg0;
  }

  // 这是initializingbean接口方法
  @override
  public void afterpropertiesset() throws exception {
    system.out
        .println("【initializingbean接口】调用initializingbean.afterpropertiesset()");
  }

  // 这是diposiblebean接口方法
  @override
  public void destroy() throws exception {
    system.out.println("【diposiblebean接口】调用diposiblebean.destory()");
  }

  // 通过<bean>的init-method属性指定的初始化方法
  public void myinit() {
    system.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
  }

  // 通过<bean>的destroy-method属性指定的初始化方法
  public void mydestory() {
    system.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
  }
}

 2、接下来是演示beanpostprocessor接口的方法,如下:

package springbeantest;

import org.springframework.beans.beansexception;
import org.springframework.beans.factory.config.beanpostprocessor;

public class mybeanpostprocessor implements beanpostprocessor {

  public mybeanpostprocessor() {
    super();
    system.out.println("这是beanpostprocessor实现类构造器!!");
    // todo auto-generated constructor stub
  }

  @override
  public object postprocessafterinitialization(object arg0, string arg1)
      throws beansexception {
    system.out
    .println("beanpostprocessor接口方法postprocessafterinitialization对属性进行更改!");
    return arg0;
  }

  @override
  public object postprocessbeforeinitialization(object arg0, string arg1)
      throws beansexception {
    system.out
    .println("beanpostprocessor接口方法postprocessbeforeinitialization对属性进行更改!");
    return arg0;
  }
}

如上,beanpostprocessor接口包括2个方法postprocessafterinitialization和postprocessbeforeinitialization,这两个方法的第一个参数都是要处理的bean对象,第二个参数都是bean的name。返回值也都是要处理的bean对象。这里要注意。 

3、instantiationawarebeanpostprocessor 接口本质是beanpostprocessor的子接口,一般我们继承spring为其提供的适配器类instantiationawarebeanpostprocessor adapter来使用它,如下:

package springbeantest;

import java.beans.propertydescriptor;

import org.springframework.beans.beansexception;
import org.springframework.beans.propertyvalues;
import org.springframework.beans.factory.config.instantiationawarebeanpostprocessoradapter;

public class myinstantiationawarebeanpostprocessor extends
    instantiationawarebeanpostprocessoradapter {

  public myinstantiationawarebeanpostprocessor() {
    super();
    system.out
        .println("这是instantiationawarebeanpostprocessoradapter实现类构造器!!");
  }

  // 接口方法、实例化bean之前调用
  @override
  public object postprocessbeforeinstantiation(class beanclass,
      string beanname) throws beansexception {
    system.out
        .println("instantiationawarebeanpostprocessor调用postprocessbeforeinstantiation方法");
    return null;
  }

  // 接口方法、实例化bean之后调用
  @override
  public object postprocessafterinitialization(object bean, string beanname)
      throws beansexception {
    system.out
        .println("instantiationawarebeanpostprocessor调用postprocessafterinitialization方法");
    return bean;
  }

  // 接口方法、设置某个属性时调用
  @override
  public propertyvalues postprocesspropertyvalues(propertyvalues pvs,
      propertydescriptor[] pds, object bean, string beanname)
      throws beansexception {
    system.out
        .println("instantiationawarebeanpostprocessor调用postprocesspropertyvalues方法");
    return pvs;
  }
}

这个有3个方法,其中第二个方法postprocessafterinitialization就是重写了beanpostprocessor的方法。第三个方法postprocesspropertyvalues用来操作属性,返回值也应该是propertyvalues对象。

4、演示工厂后处理器接口方法,如下:

package springbeantest;

import org.springframework.beans.beansexception;
import org.springframework.beans.factory.config.beandefinition;
import org.springframework.beans.factory.config.beanfactorypostprocessor;
import org.springframework.beans.factory.config.configurablelistablebeanfactory;

public class mybeanfactorypostprocessor implements beanfactorypostprocessor {

  public mybeanfactorypostprocessor() {
    super();
    system.out.println("这是beanfactorypostprocessor实现类构造器!!");
  }

  @override
  public void postprocessbeanfactory(configurablelistablebeanfactory arg0)
      throws beansexception {
    system.out
        .println("beanfactorypostprocessor调用postprocessbeanfactory方法");
    beandefinition bd = arg0.getbeandefinition("person");
    bd.getpropertyvalues().addpropertyvalue("phone", "110");
  }

}

 5、配置文件如下beans.xml,很简单,使用applicationcontext,处理器不用手动注册:

<?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:p="http://www.springframework.org/schema/p"
  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemalocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

  <bean id="beanpostprocessor" class="springbeantest.mybeanpostprocessor">
  </bean>

  <bean id="instantiationawarebeanpostprocessor" class="springbeantest.myinstantiationawarebeanpostprocessor">
  </bean>

  <bean id="beanfactorypostprocessor" class="springbeantest.mybeanfactorypostprocessor">
  </bean>
  
  <bean id="person" class="springbeantest.person" init-method="myinit"
    destroy-method="mydestory" scope="singleton" p:name="张三" p:address="广州"
    p:phone="15900000000" />

</beans>

6、下面测试一下:

package springbeantest;

import org.springframework.context.applicationcontext;
import org.springframework.context.support.classpathxmlapplicationcontext;

public class beanlifecycle {

  public static void main(string[] args) {

    system.out.println("现在开始初始化容器");
    
    applicationcontext factory = new classpathxmlapplicationcontext("springbeantest/beans.xml");
    system.out.println("容器初始化成功");  
    //得到preson,并使用
    person person = factory.getbean("person",person.class);
    system.out.println(person);
    
    system.out.println("现在开始关闭容器!");
    ((classpathxmlapplicationcontext)factory).registershutdownhook();
  }
}

关闭容器使用的是实际是abstractapplicationcontext的钩子方法。

我们来看一下结果:

现在开始初始化容器
2014-5-18 15:46:20 org.springframework.context.support.abstractapplicationcontext preparerefresh
信息: refreshing org.springframework.context.support.classpathxmlapplicationcontext@19a0c7c: startup date [sun may 18 15:46:20 cst 2014]; root of context hierarchy
2014-5-18 15:46:20 org.springframework.beans.factory.xml.xmlbeandefinitionreader loadbeandefinitions
信息: loading xml bean definitions from class path resource [springbeantest/beans.xml]
这是beanfactorypostprocessor实现类构造器!!
beanfactorypostprocessor调用postprocessbeanfactory方法
这是beanpostprocessor实现类构造器!!
这是instantiationawarebeanpostprocessoradapter实现类构造器!!
2014-5-18 15:46:20 org.springframework.beans.factory.support.defaultlistablebeanfactory preinstantiatesingletons
信息: pre-instantiating singletons in org.springframework.beans.factory.support.defaultlistablebeanfactory@9934d4: defining beans [beanpostprocessor,instantiationawarebeanpostprocessor,beanfactorypostprocessor,person]; root of factory hierarchy
instantiationawarebeanpostprocessor调用postprocessbeforeinstantiation方法
【构造器】调用person的构造器实例化
instantiationawarebeanpostprocessor调用postprocesspropertyvalues方法
【注入属性】注入属性address
【注入属性】注入属性name
【注入属性】注入属性phone
【beannameaware接口】调用beannameaware.setbeanname()
【beanfactoryaware接口】调用beanfactoryaware.setbeanfactory()
beanpostprocessor接口方法postprocessbeforeinitialization对属性进行更改!
【initializingbean接口】调用initializingbean.afterpropertiesset()
【init-method】调用<bean>的init-method属性指定的初始化方法
beanpostprocessor接口方法postprocessafterinitialization对属性进行更改!
instantiationawarebeanpostprocessor调用postprocessafterinitialization方法
容器初始化成功
person [address=广州, name=张三, phone=110]
现在开始关闭容器!
【diposiblebean接口】调用diposiblebean.destory()
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法

以上就是对java spring bean 生命周期的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!