Spring的@PostConstruct和@PreDestroy

当我们使用依赖注入配置Spring Beans时,有时我们希望在我们的Bean开始为客户端请求提供服务之前确保一切都初始化正确。同样地,当上下文被销毁时,我们可能需要关闭一些由Spring Bean使用的资源。

春天的@PostConstruct

当我们用@SpringBean的@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或更低版本,则无需添加上述依赖项。

春天的 @PreDestroy

当我们使用PreDestroy注解对一个Spring Bean方法进行注解时,当bean实例从上下文中移除时,该方法将被调用。理解这一点非常重要-如果您的Spring Bean作用域为“prototype”,那么它并不完全由Spring容器管理,PreDestroy方法将不会被调用。如果存在名为shutdown或close的方法,Spring容器将尝试在销毁bean时自动配置它们作为回调方法。

Spring @PostConstruct和@PreDestroy示例

这是一个带有@PostConstruct和@PreDestroy方法的简单的Spring bean。

package com.Olivia.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.Olivia.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.Olivia.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

当@Bean实例化之后,@PostConstruct方法被调用。当上下文关闭时,它会同时调用shutdown和close方法。

Spring在原型作用域下的@PostConstruct和@PreDestroy

只需将MyConfiguration中的scope值更改为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代码库中查看完整的项目代码。

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds