首页 > 代码库 > Spring Bean的生命周期

Spring Bean的生命周期

在传统的java应用中,bean的生命周期由new进行bean的实例化,然后该bean就可以使用了,当bean不被使用时,由java自动进行垃圾回收。

然而Spring的生命周期相对比较复杂:

1.Spring对bean进行实例化,即调用构造器

public MyBean01(){        System.out.println("MyBean01 构造");    }

 

2.Spring将值和bean的引用注入到bean对应的属性中,即调用set~方法

public void setName(String name) {        System.out.println("MyBean01  值注入属性中");        this.name = name;    }

 

3.如果该bean实现了BeanNameAware接口,Spring将bean的id传递给setBeanName()方法

@Override    public void setBeanName(String name) {        System.out.println("MyBean01 id: "+name);    }

4.如果该bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory实例传入

@Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        System.out.println("BeanFactory 中有 b1 这个bean: "+beanFactory.containsBean("b1"));        System.out.println("BeanFactory 调用MyBean02.class:"+beanFactory.getBean(MyBean02.class).toString());    }

5.如果该bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入

@Override    public void setApplicationContext(ApplicationContext applicationContext)            throws BeansException {        applicationContext.isSingleton(name);    }

6.如果bean实现了BeanPostProcessor接口,Spring将调用它的postProcessBeforeInitialization方法

@Override    public Object postProcessBeforeInitialization(Object bean, String beanName)            throws BeansException {                //在这里可以修改bean的属性,返回时得返回bean,不然程序不予执行        return bean;    }

7.如果bean实现了InitializingBean接口,Spring将调用它的afterPropertiesSet()方法,另一种方法是在xml文件中配置init-method

<bean id="b1" class="com.spring.cycle.MyBean01"         init-method="init" 
     destroy-method="distory"> <property name="name" value=http://www.mamicode.com/"tom"></property></bean>

8.如果bean实现了BeanPostProcessor接口,Spring将调用它的postProcessAfterInitialization,与步骤6协同操作卡住步骤7(init)

@Override    public Object postProcessAfterInitialization(Object bean, String beanName)            throws BeansException {        // TODO Auto-generated method stub        return null;    }

9.此时,bean已经准备就绪,一直存在应用上下文中,直到该应用上下文被销毁

10.当应用上下文关闭时,如果bean实现了DisposableBean接口,Spring将调用它的destory()方法,或者在xml文件中配置destory-method

 

以下是4段代码,以供测试

package com.spring.cycle;import org.springframework.beans.factory.BeanNameAware;public class MyBean01 implements BeanNameAware{        public MyBean01(){        System.out.println("MyBean01 构造");    }    @Override    protected void finalize() throws Throwable {        System.out.println("MyBean01 finalize");        super.finalize();    }    public void init(){        System.out.println("MyBean01 init");    }    public void distory(){        System.out.println("MyBean01 distory");    }        private String name;        public void setName(String name) {        System.out.println("MyBean01  值注入属性中");        this.name = name;    }        @Override    public String toString() {        return "MyBean01: name--> "+name;    }    @Override    public void setBeanName(String name) {        System.out.println("MyBean01 id: "+name);    }}
package com.spring.cycle;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class MyBean02 implements BeanFactoryAware,ApplicationContextAware,BeanPostProcessor{        public MyBean02(){        System.out.println("MyBean02 构造");    }    @Override    protected void finalize() throws Throwable {        System.out.println("MyBean02 finalize");        super.finalize();    }    private void init(){        System.out.println("MyBean02 init");    }    private void distory(){        System.out.println("MyBean02 distory");    }        private String name;    public void setName(String name) {        System.out.println("MyBean02  值注入属性中");        this.name = name;    }        @Override    public String toString() {        return "MyBean02: name--> "+name;    }    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        System.out.println("MyBean02 BeanFactory 中有 b1 这个bean: "+beanFactory.containsBean("b1"));        System.out.println("MyBean02 BeanFactory 调用MyBean02.class:"+beanFactory.getBean(MyBean02.class).toString());    }    @Override    public void setApplicationContext(ApplicationContext applicationContext)            throws BeansException {        //applicationContext.isSingleton(name);        System.out.println("MyBean02 applicationContext.......");    }    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName)            throws BeansException {                //在这里可以修改bean的属性,返回时得返回bean,不然程序不予执行        return bean;    }    @Override    public Object postProcessAfterInitialization(Object bean, String beanName)            throws BeansException {        // TODO Auto-generated method stub        return null;    }}
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="b1" class="com.spring.cycle.MyBean01"         init-method="init" destroy-method="distory">         <property name="name" value=http://www.mamicode.com/"tom"></property>    </bean>    <bean id="b2" class="com.spring.cycle.MyBean02"         init-method="init" destroy-method="distory">         <property name="name" value=http://www.mamicode.com/"jerry"></property>        </bean></beans>
package com.spring.cycle;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMain {    public static void main(String[] args) {                ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("com/spring/cycle/bean-cycle.xml");                MyBean01  b1 = (MyBean01) context.getBean("b1");        MyBean02  b2 = (MyBean02) context.getBean("b2");                System.out.println(b1);        System.out.println(b2);                         context.close();    }}

 

Spring Bean的生命周期