Spring中Bean的生命周期 初步研究

    1. Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,

        如果实现就调用bean的afterPropertiesSet方法。

        另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;

        否则每次创建bean时afterPropertiesSet方法都会被重新调用。

    2. Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。

    3. Spring要求这个init-method方法是一个无参数的方法,如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init-method,任何一个方法出错都会导致spring创建bean失败。如果afterPropertiesSet方法调用失败,也不会再继续执行init-mehtod方法。

      下面看一个简单的例子:

<bean id="person1" class="spring.ioc.beanfactory.Person" init-method="init" 
        p:name="spring注入-nicholaslee" 
        p:age="1" />
package spring.ioc.beanfactory;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Person implements InitializingBean,DisposableBean  {
    
    private String name;
    private int age; 
    
    public Person(){
        System.out.println("--------构造方法在调用");
        this.name = "默认用户名";
        this.age= 0;
        System.out.println(this);
    } 
    
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    } 

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    public void init(){
        System.out.println("--------init()在调用");
        this.name="init";
        this.age=998;
        System.out.println(this); 
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("--------afterPropertiesSet()在调用");
        this.age=999;
        System.out.println(this); 
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("--------destroy()在调用"); 
    }

}

在启动容器的时候我们可以在控制台看到如下打印内容和顺序:

--------构造方法在调用
Person{name='默认用户名', age=0}
--------afterPropertiesSet()在调用
Person{name='spring注入-nicholaslee', age=999}
--------init()在调用
Person{name='init', age=998}

------------------------------------------------------------------------

总结:

Bean的实例化是Bean生命周期的一个非常重要的环节,一般来说,初始化后,就不再改变了,直到bean被从BeanFactory中显式的移除。
 
当从BeanFactory中通过getBean()方法获取一个bean的时候,BeanFactory会经过如下的步骤来构建Bean的实例,这正是实例化Bean的过程:
 
1、调用Bean的默认构造方法,或者在指定的构造方法,生成bean实例(暂称为instance1);
3、如果Bean的配置文件中注入了Bean属性值,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的。
2、如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或操作instance2,得到instance3;
4、如果Bean的配置文件中指定了init-method="init"属性,则会调用指定的初始化方法,则在instance3的基础上调用初始化方法init(),将对象最终初始化为instance4;当然,这个初始化的名字是任意的。
 
实际上,instance1、2、3、4仅仅是一个实例在不同阶段的状态。

转载于:https://www.cnblogs.com/NicholasLee/archive/2012/07/08/2581851.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值