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/