Spring @PostConstruct 和 @PreDestroy
当我们使用依赖注入配置Spring Beans时,有时我们希望确保在我们的 bean 开始服务客户端请求之前一切都已正确初始化。同样,当上下文被销毁时,我们可能必须关闭 spring bean 使用的一些资源。
春季@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
方法不会被调用。如果有一个名为shutdown
或的方法close
,那么当 bean 被销毁时,spring 容器将尝试自动将它们配置为回调方法。
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();
}
}
我不需要明确指定我的 bean 为单例,但稍后我会将其值更改为“prototype”,并查看@PostConstruct和@PreDestroy方法会发生什么。这是我的主类,我在其中创建了 spring 上下文并获取了几个 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
只需将范围值更改为原型并MyConfiguration
运行主类。您将获得如下所示的输出。
MyBean instance created
Verifying Resources
1640296160
MyBean instance created
Verifying Resources
1863374262
So it’s clear that spring container is initializing the bean on every request, calling its @PostConstruct method and then handing it over to the client. Spring is not managing the bean after that and in this case, the client has to perform all the resource cleanup by directly calling the PreDestroy method.
Summary
@PostConstruct and @PreDestroy and important annotations to use with the spring bean lifecycle management. We can use them to verify that bean is properly initialized and then close all the resources when the bean is removed from the spring context.
You can check out the complete project code from our GitHub Repository.