1. Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,
如果实现就调用bean的afterPropertiesSet方法。
另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;
否则每次创建bean时afterPropertiesSet方法都会被重新调用。
2. Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。
3. Spring要求这个init-method方法是一个无参数的方法,如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init-method,任何一个方法出错都会导致spring创建bean失败。如果afterPropertiesSet方法调用失败,也不会再继续执行init-mehtod方法。
下面看一个简单的例子:
<bean id="person1" class="spring.ioc.beanfactory.Person" init-method="init" p:name="spring注入-nicholaslee" p:age="1" />
package spring.ioc.beanfactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class Person implements InitializingBean,DisposableBean { private String name; private int age; public Person(){ System.out.println("--------构造方法在调用"); this.name = "默认用户名"; this.age= 0; System.out.println(this); } public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } 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 void init(){ System.out.println("--------init()在调用"); this.name="init"; this.age=998; System.out.println(this); } @Override public void afterPropertiesSet() throws Exception { System.out.println("--------afterPropertiesSet()在调用"); this.age=999; System.out.println(this); } @Override public void destroy() throws Exception { System.out.println("--------destroy()在调用"); } }
在启动容器的时候我们可以在控制台看到如下打印内容和顺序:
--------构造方法在调用
Person{name='默认用户名', age=0}
--------afterPropertiesSet()在调用
Person{name='spring注入-nicholaslee', age=999}
--------init()在调用
Person{name='init', age=998}
------------------------------------------------------------------------
总结: