spring中的DisposableBean和InitializingBean
在spring容器初始化bean和銷燬bean的以前的操作有很多種,目前我知道的有:在xml中定義的時候用init-method和destory-method,
還可以使用beans的default-init-method和default-destroy-method屬性來設定所有bean的預設的初始化和銷燬方法。(這種情況下如果bean有對應的方法則會執行對應的初始化和銷燬方法)。
定義一個Demon類:
package com.moonlit.myspring; public class Demon { public void defaultBorn() { System.out.println("the demon was born."); } public void doAction() { System.out.println("the demon do destroys"); } public void defaultDead() { System.out.println("the demon is dead."); } }
配置其Bean:
<bean id="demon" class="com.moonlit.myspring.Demon" />
我們配置beans的default-init-method和default-destroy-method屬性如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-init-method="defaultBorn" default-destroy-method="defaultDead" >
可以使用bean的init-method和destroy-method屬性來初始化和銷燬bean。
定義一個Hero類:
package com.moonlit.myspring; public class Hero { public void born() { System.out.println("the hero is born."); } public void defaultBorn() { System.out.println("the hero is born by default."); } public void doAction() { System.out.println("the hero save the world."); } public void dead() { System.out.println("the hero is dead."); } public void defaultDead() { System.out.println("the hero was dead by default."); } }
配置其bean:
<bean id="hero" class="com.moonlit.myspring.Hero"
init-method="born"
destroy-method="dead" />
測試package com.moonlit.practice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.moonlit.myspring.Demon;
import com.moonlit.myspring.Hero;
public class PracticeHero {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring-idol.xml");
Hero hero = (Hero) context.getBean("hero");
hero.doAction();
Demon demon = (Demon) context.getBean("demon");
demon.doAction();
}
}
輸出結果如下:
the hero is born.
the demon was born.
the hero save the world.
the demon do destroys
不能看到銷燬的效果,可能是因為程式結束的時候物件還沒有執行銷燬的方法。(暫時還不知道怎麼檢測destroy-method),但是可以看到init-method的方法。因為Hero的bean定義了init-method和destroy-method,所以程式會先找born()和dead()兩個方法執行;但是Demon的bean沒有定義init-method方法和destroy-method方法,所以程式會執行beans裡面定義的default-init-method和default-destroy-method方法執行,所以輸出的效果是這樣的。
理解:使用bean元素的init-method和destroy-method元素可以定義一個bean在初始化和銷燬時使用的方法;也可以通過beans的default-init-method和default-destroy-method元素來指定所有bean的預設初始化和銷燬的方法。
還有一種就是定義bean的時候實現DisposableBean和InitializingBean 這兩個介面,
package com.moonlit.myspring;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Spiderman implements InitializingBean, DisposableBean {
public void destroy() throws Exception {
System.out.println("the spider man is dead...He will be back.");
}
public void doAction() {
System.out.println("spider man saved Gotham City");
}
public void afterPropertiesSet() throws Exception {
System.out.println("The Dark Knight Rises");
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring-idol.xml");
Spiderman spiderman = (Spiderman) context.getBean("spiderman");
spiderman.doAction();
}
}
輸出效果如下:
the hero is born.
the demon was born.
The Dark Knight Rises
spider man saved Gotham City
開啟InitializingBean 的原始碼:
public interface InitializingBean {
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and applicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;
}
根據註解很清楚的可以看出,afterPropertiesSet()表示在資源載入完以後,初始化bean之前執行的方法,我猜想spring底層應該會在初始化bean的時候,應該會使用(bean instanceof InitializingBean)判斷是不是實現了這個介面,其實在很多框架中都是這麼幹的,但是因為沒研究過spring原始碼,暫且還不知道底層原理。這樣我們就可以在初始化的時候,做一些自己想要做的事了。
同理,DisposableBean就是在一個bean被銷燬的時候,spring容器會幫你自動執行這個方法,估計底層原理也是差不多的,對於一些使用完之後需要釋放資源的bean,我們都會實現這個介面,或者是配置destory-method方法。原始碼也基本是相似的,只是把afterPropertiesSet改為destroy。