Spring BeanFactory实例化Bean的过程

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仅仅是一个实例在不同阶段的状态。
 
下面给一个简单的例子验证一下上面的结论:
 
public class Person implements InitializingBean, DisposableBean { 
    private String name; 
    private int age; 


    public Person(){ 
        System.out.println("--------|| 构造方法在调用..."); 
        this.name = "默认用户名"
        this.age= 250; 
        System.out.println(this); 
    } 

    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 String toString() { 
        return "Person{" + 
                "name='" + name + '\'' + 
                ", age=" + age + 
                '}'; 
    } 

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

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

    public void destroy() throws Exception { 
        System.out.println("--------|| destroy()正在调用..."); 
    } 
}
 
public class BeanContextHelper { 
    private static ApplicationContext _instance; 

    static { 
        if (_instance == null) _instance = buildApplicationContext(); 
    } 

    private BeanContextHelper() { 
    } 

    /** 
     * 重新构建ApplicationContext对象 
     * 
     * @return ApplicationContext 
     */
 
    public static ApplicationContext buildApplicationContext() { 
        return new ClassPathXmlApplicationContext("applicationContext.xml"); 
    } 

    /** 
     * 获取一个ApplicationContext对象 
     * 
     * @return ApplicationContext 
     */
 
    public static ApplicationContext getApplicationContext() { 
        return _instance; 
    } 
}
 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 

<beans> 
    <bean id="person" class="com.lavasoft.springnote.ch01.Person" init-method="init" destroy-method="destroy"> 
        <property name="name"> 
            <value>lavasoft</value> 
        </property> 
        <property name="age"> 
            <value>22</value> 
        </property> 
    </bean> 
</beans>
 
/** 
* Created by IntelliJ IDEA.<br> 
* <b>User</b>: leizhimin<br> 
* <b>Date</b>: 2008-4-17 16:58:07<br> 
* <b>Note</b>: 客户端测试 
*/
 
public class Test { 
    public static void main(String args[]) { 
        Test test = new Test(); 
        test.test(); 

    } 
    public void test(){ 
        ApplicationContext context = BeanContextHelper.getApplicationContext(); 
        Person person = (Person) context.getBean("person"); 
        System.out.println("--------|| 从Spring BeanFactory获取person..."); 
        System.out.println(person); 
    } 
}
 
运行结果:
 
--------|| 构造方法在调用... 
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory). 
log4j:WARN Please initialize the log4j system properly. 
Person{name='默认用户名', age=250} 
--------|| afterPropertiesSet()正在调用... 
Person{name='lavasoft', age=999} 
--------|| init()正在调用... 
Person{name='init', age=998} 
--------|| 从Spring BeanFactory获取person... 
Person{name='init', age=998} 

Process finished with exit code 0
 
从控制台打印出来的信息可以很清楚看明白Bean实例化的过程。
 
对Person中实现的几个接口功能做个简单介绍:
BeanNameAware
只有一个方法void setBeanName(String name),用来设置bean的名字.
DisposableBean
为Bean的销毁提供回调功能,在bean实例销毁前调用接口的destroy()方法.
InitializingBean
Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。
 

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/74806,如需转载请自行联系原作者
上一篇:netty案例,netty4.1中级拓展篇七《Netty请求响应同步通信》


下一篇:netty案例,netty4.1基础入门篇六《NettyServer群发消息》