Spring BeanFactory實例化Bean的過程
Bean的實例化是Bean生命週期的一個很是重要的環節,通常來講,初始化後,就再也不改變了,直到bean被從BeanFactory中顯式的移除。
當從BeanFactory中經過getBean()方法獲取一個bean的時候,BeanFactory會通過以下的步驟來構建Bean的實例,這正是實例化Bean的過程:
一、調用Bean的默認構造方法,或者在指定的構造方法,生成bean實例(暫稱爲instance1);
三、若是Bean的配置文件中注入了Bean屬性值,則在instance1基礎上進行屬性注入造成instance2,這種注入是覆蓋性的。
二、若是Bean實現了InitializingBean接口,則調用afterPropertiesSet()方法,來改變或操做instance2,獲得instance3;
四、若是Bean的配置文件中指定了init-method="init"屬性,則會調用指定的初始化方法,則在instance3的基礎上調用初始化方法init(),將對象最終初始化爲instance4;固然,這個初始化的名字是任意的。
實際上,instance一、二、三、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()。