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()。

forwarded from http://lavasoft.blog.51cto.com/62575/74806/

你可能感兴趣的:(Spring BeanFactory实例化Bean的过程)