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/