1. 引言
Spring 允許我們為 Bean 的創建和銷燬附加自定義操作。例如,我們可以通過實現 InitializingBean 和 DisposableBean 接口來完成。
在本快速教程中,我們將探討另一種可能性,即 @PostConstruct 和 @PreDestroy 註解。
2. <em @PostConstruct
Spring 只會調用帶有 註解的方法一次,在 Bean 屬性初始化之後立即執行。請注意,即使沒有需要初始化任何內容,這些方法也會運行。
帶有 註解的方法可以具有任何訪問級別,但不能是靜態的。
@PostConstruct 的一種可能用途是填充數據庫。例如,在開發過程中,我們可能想要創建一些默認用户:
@Component
public class DbInit {
@Autowired
private UserRepository userRepository;
@PostConstruct
private void postConstruct() {
User admin = new User("admin", "admin password");
User normalUser = new User("user", "user password");
userRepository.save(admin, normalUser);
}
}上述示例首先會初始化 UserRepository,然後運行 @PostConstruct 方法。
3. @PreDestroy
標註了 @PreDestroy 的方法僅在 Spring 從應用程序上下文移除我們的 Bean 之前執行一次。
與 @PostConstruct 類似,標註了 @PreDestroy 的方法可以具有任何訪問級別,但不能是靜態的。
@Component
public class UserRepository {
private DbConnection dbConnection;
@PreDestroy
public void preDestroy() {
dbConnection.close();
}
}此方法的目的是釋放資源或執行其他清理任務,例如關閉數據庫連接,在 Bean 被銷燬之前。
4. javax.annotation 或 jakarta.annotation
從 JDK 6 到 JDK 8,@PostConstruct 和 @PreDestroy 註解屬於標準 Java 庫中的 javax.annotation 包。但是,在 JDK 9 中,整個 javax.annotation 包從核心 Java 模塊中移除,並在 JDK 11 中完全消失。在 Jakarta EE 9 中,該包已遷至 jakarta.annotation。
因此,我們有時會問:“我應該使用來自 javax.annotation 還是 jakarta annotation 的註解?”這取決於我們使用的 Spring 版本。 為了快速理解 Spring、JDK、javax 和 jakarta 命名空間之間的兼容性,讓我們用表格總結如下:
| Spring 版本 | JDK 版本 | Java / Jakatar 命名空間 |
|---|---|---|
| 6.1.x | JDK 17 到 JDK 23 | jakarta |
| 6.0.x | JDK 17 到 JDK 21 | jakarta |
| 5.3.x | JDK 8 到 JDK 21 | javax |
如上表所示,對於 Spring 6.0.x 和 6.1.x,我們應該使用 jakarta 命名空間。但是,如果我們的項目使用 Spring 5.3.x 和 JDK 9 或更高版本,因為 Spring 5.3.x 僅支持 javax 命名空間,則必須在我們的項目中顯式添加 javax.annotation-api 依賴:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>上述 XML 展示了將 javax.annotation-api 依賴添加到 Maven 項目的 pom.xml 中的示例。
5. 結論
在本文中,我們學習瞭如何使用 @PostConstruct 和 @PreDestroy 註解。