当前位置: 移动技术网 > IT编程>开发语言>Java > Spring Bean的生命周期详细介绍

Spring Bean的生命周期详细介绍

2019年07月22日  | 移动技术网IT编程  | 我要评论

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

一、生命周期流程图:

  spring bean的完整生命周期从创建spring容器开始,直到最终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 生命周期的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网