之前項目中,需要用到在項目啓動時,就要在某個類中執行一些方法。在我的記憶中我只知道在bean的配置中加init-method這種方法。這兩天在瀏覽spring官方文檔中,發現還有其他的方法,於是拿出來總結一下,以方便後續開發中使用。
spring在控制bean生命週期的整個過程中,給開發者提供了初始化與銷燬bean時需要做自己的處理的三種方式(我用的spring5.1.3版本)
1.在需要bean初始化、銷燬時執行的方法前加@PostConstruct或@PreDestroy
例如:
@PostConstruct
public void populate() {
System.out.println("實現@PostConstruct的方法");
}
@PreDestroy
public void clear() {
System.out.println("實現@PreDestroy的方法");
}
2.使需要擁有初始化、銷燬的方法的bean實現InitializingBean,DisposableBean兩個接口
例如:
public class Demo implements InitializingBean,DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("實現InitializingBean接口的方法");
}
@Override
public void destroy() throws Exception {
System.out.println("實現DisposableBean接口的方法");
}
}
3.需要在spring配置文件相關bean的配置中添加init-method="方法名" destroy-method="方法名"屬性
例如:
配置文件:
<bean id="demo" class="com.Demo" init-method="init" destroy-method="over" lazy-init="false"/>
代碼:
public class Demo{
public void init(){
System.out.println("init");
}
public void over(){
System.out.println("over");
}
}
lazy-init="false"這個屬性是爲了,防止類在項目用到此類時才加載的控制,我這沒有加lazy-init="false"其實也生效的。這個要看你的類配置在作用項目全局中,還是某個servlet作用域中。
我在一個類中分別實現了這三種方式,如下:
@Component
public class Demo implements InitializingBean,DisposableBean {
//@Resource(name = "algorithmProperty")
//private AlgorithmProperty algorithmProperty;
public Demo() {
System.out.println("構造器");
}
public void init(){
System.out.println("init");
}
public void over(){
System.out.println("over");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("實現InitializingBean接口的方法");
}
@Override
public void destroy() throws Exception {
System.out.println("實現DisposableBean接口的方法");
}
@PostConstruct
public void populate() {
System.out.println("實現@PostConstruct的方法");
}
@PreDestroy
public void clear() {
System.out.println("實現@PreDestroy的方法");
}
}
1.啓動項目
控制檯輸出:
構造器
實現@PostConstruct的方法
實現InitializingBean接口的方法
init
2.停止項目
控制檯輸出:
實現@PreDestroy的方法
實現DisposableBean接口的方法
over
我本地實現的現象是這樣可以,啓動與停止執行三種方式的順序。重複了多次依然是一樣的,這個爲什麼只有後續研究源碼考究了。
需要注意的是:我爲什麼要加構造器呢,並且得到了執行。說明spring容器的bean控制,是通過bean的無參構造器完成的。
再一點,我的例子中,有兩行註釋的代碼:
//@Resource(name = "algorithmProperty")
//private AlgorithmProperty algorithmProperty;
通過驗證,這個類的這個屬性,一般情況下是在所有的需要spring加載的bean加載完,才進行依賴注入的。 並且注入完所有的屬性之後,才執行上述的三種實現方法。 也就是說,如果在需要某個bean初始化時,執行你自定義的方法,你的方法中又需要其他的spring控制的bean。 是不能通過添加進無參構造器來實現的,會報空指針異常。