Spring Bean的生命週期

在傳統的java應用中,bean的生命週期由new進行bean的實例化,而後該bean就可使用了,當bean不被使用時,由java自動進行垃圾回收。java

然而Spring的生命週期相對比較複雜:spring

1.Spring對bean進行實例化,即調用構造器app

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

 

2.Spring將值和bean的引用注入到bean對應的屬性中,即調用set~方法ide

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

 

3.若是該bean實現了BeanNameAware接口,Spring將bean的id傳遞給setBeanName()方法post

@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所在的應用上下文的引用傳入this

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

6.若是bean實現了BeanPostProcessor接口,Spring將調用它的postProcessBeforeInitialization方法spa

複製代碼
@Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        
        //在這裏能夠修改bean的屬性,返回時得返回bean,否則程序不予執行
        return bean;
    }
複製代碼

7.若是bean實現了InitializingBean接口,Spring將調用它的afterPropertiesSet()方法,另外一種方法是在xml文件中配置init-methodcode

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

8.若是bean實現了BeanPostProcessor接口,Spring將調用它的postProcessAfterInitialization,與步驟6協同操做卡住步驟7(init)xml

@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="tom"></property>
    </bean>
    <bean id="b2" class="com.spring.cycle.MyBean02" 
        init-method="init" destroy-method="distory"> 
        <property name="name" value="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();
    }

}
複製代碼
相關文章
相關標籤/搜索