Spring @PostConstruct 和 @PreDestroy

當我們使用Spring Beans配置依賴注入時,有時我們希望在我們的bean開始處理客戶端請求之前確保一切都被正確初始化。同樣,在上下文被銷毀時,我們可能需要關閉一些由Spring Bean使用的資源。

Spring @PostConstruct

當我們在Spring Bean中的方法上註釋@PostConstruct時,它會在Spring Bean初始化後執行。我們只能有一個使用@PostConstruct註釋的方法。這個註釋是Common Annotations API的一部分,也是JDK模塊javax.annotation-api的一部分。因此,如果您在Java 9或更高版本中使用此註釋,您將不得不明確地將此jar添加到您的項目中。如果您使用maven,則應添加以下依賴項。

<dependency>
	<groupId>javax.annotation</groupId>
	<artifactId>javax.annotation-api</artifactId>
	<version>1.3.2</version>
</dependency>

如果您使用的是Java 8或更低版本,則無需添加上述依賴項。

Spring @PreDestroy

當我們用PreDestroy註釋一個Spring Bean方法時,當bean實例從上下文中移除時,該方法會被調用。這是一個非常重要的點要理解 – 如果您的spring bean作用域是“原型”,那麼它不完全由spring容器管理,PreDestroy方法將不會被調用。如果有一個名為shutdownclose的方法,那麼spring容器將嘗試在bean被銷毀時自動配置它們作為回調方法。

Spring @PostConstruct@PreDestroy示例

這是一個帶有@PostConstruct@PreDestroy方法的簡單的spring bean。

package com.journaldev.spring;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}

	@PostConstruct
	private void init() {
		System.out.println("Verifying Resources");
	}

	@PreDestroy
	private void shutdown() {
		System.out.println("Shutdown All Resources");
	}

	public void close() {
		System.out.println("Closing All Resources");
	}
}

請注意,我還定義了一個close方法,以檢查當我們的bean被銷毀時是否被調用。這是我簡單的spring配置類。

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class MyConfiguration {
	
    @Bean
    @Scope(value="singleton")
    public MyBean myBean() {
	return new MyBean();
    }
	
}

I don’t need to explicitly specify my bean as a singleton but I will later change its value to “prototype” and see what happens with @PostConstruct and @PreDestroy methods. Here is my main class where I am creating spring context and getting few instances of MyBean.

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		MyBean mb1 = ctx.getBean(MyBean.class);
		System.out.println(mb1.hashCode());

		MyBean mb2 = ctx.getBean(MyBean.class);
		System.out.println(mb2.hashCode());

		ctx.close();
	}

}

當我們運行上述類時,我們獲得以下輸出。

MyBean instance created
Verifying Resources
1640296160
1640296160
Shutdown All Resources
Closing All Resources

所以 @PostConstruct 方法是在bean实例化后调用的。当上下文关闭时,它会同时调用shutdown和close方法。

Spring @PostConstruct @PreDestroy 与Prototype范围

只需将 MyConfiguration 中的作用域值更改为 prototype 并运行主类。您将获得以下输出。

MyBean instance created
Verifying Resources
1640296160
MyBean instance created
Verifying Resources
1863374262

因此,显然spring容器正在根据每个请求初始化bean,调用其 @PostConstruct 方法,然后将其交给客户端。在这种情况下,Spring不再管理bean,而在这种情况下,客户端必须通过直接调用PreDestroy方法来执行所有资源清理。

摘要

@PostConstruct@PreDestroy是與Spring Bean生命周期管理一起使用的重要註釋。我們可以使用它們來驗證Bean是否正確初始化,然後在Bean從Spring上下文中移除時關閉所有資源。

您可以從我們的GitHub存儲庫中查看完整的專案代碼。

Source:
https://www.digitalocean.com/community/tutorials/spring-postconstruct-predestroy