了解Spring bean 生命周期。我们将了解 bean生命周期阶段、初始化和销毁回调方法。我们将学习使用 XML 配置以及 Java 注释配置来自定义 bean 生命周期事件。
1. 什么是 Bean 的生命周期?
Spring bean 需要在容器启动时根据 Java 或 XML bean 定义进行实例化。框架可能还需要执行一些初始化前和初始化后的步骤,以使 bean 进入可用状态。
之后,当不再需要 bean 时,会将其从 IoC 容器中移除。与初始化阶段一样,Spring 框架可能需要执行销毁前和销毁后的步骤以释放其他系统资源。
Spring bean 工厂负责管理在 Spring 容器中创建的 bean 的生命周期回调。
1.1。生命周期回调方法
Spring bean factory 控制 bean 的创建和销毁。为了执行一些自定义代码,bean 工厂提供了回调方法,大致可以分为两类:
- 初始化后回调方法
- 预销毁回调方法
2. 如何自定义 Bean 生命周期
Spring框架提供了以下四种方式来控制和实现一个bean的生命周期事件:
InitializingBean
和DisposableBean
回调接口- *特定行为的感知接口
- bean配置文件中的自定义
init()
和方法destroy()
@PostConstruct
和@PreDestroy
注释
让我们详细了解每种方式。
2.1。InitializingBean 和 DisposableBean 接口
org.springframework.beans.factory.InitializingBean接口允许 bean 在容器设置了 bean 的所有必要属性后执行初始化工作。
该InitializingBean
接口指定了一个方法:
void afterPropertiesSet() throws Exception;
该afterPropertiesSet()
方法不是初始化 bean 的首选方法,因为它将 bean 类与 spring 容器紧密耦合。更好的方法是在applicationContext.xml
.
类似地,实现org.springframework.beans.factory.DisposableBean接口允许 bean 在 Spring 容器销毁 bean 之前获得回调。
该DisposableBean
接口指定了一个方法:
void destroy() throws Exception;
实现上述接口的示例 bean 如下所示:
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class DemoBean implements InitializingBean, DisposableBean
{
//Other bean attributes and methods
@Override
public void afterPropertiesSet() throws Exception
{
//Bean initialization code
}
@Override
public void destroy() throws Exception
{
//Bean destruction code
}
}
2.2. *Aware 接口以添加特定行为
Spring 提供了一系列接口,允许 bean 向容器指示它们需要特定的基础设施依赖项。
这些 Aware 接口中的每一个都需要我们实现一个方法来将依赖项注入 bean。
我们可以将这些接口总结为:
感知界面 | 重写的方法 | 目的 |
---|---|---|
ApplicationContextAware |
void setApplicationContext (ApplicationContext applicationContext) 抛出 BeansException; |
由任何希望通知ApplicationContext 它在其中运行的对象实现的接口。 |
ApplicationEventPublisherAware |
无效setApplicationEventPublisher (应用事件发布者应用事件发布者); |
设置ApplicationEventPublisher 这个对象在其中运行。 |
BeanClassLoaderAware |
无效setBeanClassLoader (类加载器类加载器); |
将 bean 类加载器提供给 bean 实例的回调。 |
BeanFactoryAware |
void setBeanFactory (BeanFactory beanFactory) 抛出 BeansException; |
将拥有工厂提供给 bean 实例的回调。 |
BeanNameAware |
无效setBeanName (字符串名称); |
在创建此 bean 的 bean 工厂中设置 bean 的名称。 |
BootstrapContextAware |
无效setBootstrapContext (引导上下文引导上下文); |
设置该对象运行的 BootstrapContext。 |
LoadTimeWeaverAware |
无效setLoadTimeWeaver (加载时间韦弗加载时间韦弗); |
设置此对象的包含 ApplicationContext 的 LoadTimeWeaver。 |
MessageSourceAware |
无效setMessageSource (消息源消息源); |
设置该对象运行的 MessageSource。 |
NotificationPublisherAware |
无效setNotificationPublisher (通知发布者通知发布者); |
为当前托管资源实例设置 NotificationPublisher 实例。 |
PortletConfigAware |
无效setPortletConfig (PortletConfig portletConfig); |
设置运行此对象的 PortletConfig。 |
PortletContextAware |
无效setPortletContext (PortletContext portletContext); |
设置该对象在其中运行的 PortletContext。 |
ResourceLoaderAware |
无效setResourceLoader (资源加载器资源加载器); |
设置运行此对象的 ResourceLoader。 |
ServletConfigAware |
无效setServletConfig (ServletConfig servletConfig); |
设置该对象运行的 ServletConfig。 |
ServletContextAware |
无效setServletContext (ServletContext servletContext); |
设置该对象运行的 ServletContext。 |
Java 程序展示了 Aware 接口的使用。
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class DemoBean implements ApplicationContextAware
{
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
//Use the context in other bean methods
}
2.3. 自定义 init() 和 destroy() 方法
我们可以通过两种方式添加默认值init()
和destroy()
方法:
- 局部定义适用于单个 bean
- 全局定义适用于在整个 bean 上下文中定义的所有 bean
2.3.1。本地定义
本地init()
和destroy()
方法的配置如给定示例中所示。
<beans>
<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"
init-method="customInit"
destroy-method="customDestroy"></bean>
</beans>
2.3.2. 全局定义
<beans>
容器将为标签下给出的所有 bean 定义调用全局方法。当我们有一种为所有 bean定义通用方法名称的模式时init()
,全局覆盖很有帮助。destroy()
这个特性帮助我们不单独提及所有 bean 的 init 和 destroy 方法名称。
<beans default-init-method="customInit" default-destroy-method="customDestroy">
<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"></bean>
</beans>
基于上述本地或全局覆盖,我们必须在 bean 类中编写customInit()
和customDestroy()
方法,如下例所示。
public class DemoBean
{
public void customInit()
{
System.out.println("Method customInit() invoked...");
}
public void customDestroy()
{
System.out.println("Method customDestroy() invoked...");
}
}
2.4. @PostConstruct 和 @PreDestroy 注释
从 Spring 2.5 开始,我们可以使用@PostConstruct
和@PreDestroy
注释来指定 bean 生命周期方法。
@PostConstruct
在使用默认构造函数构造 bean 之后,并且在它的实例返回到请求对象之前,将调用带注释的方法。@PreDestroy
在 bean 即将在 bean 容器内销毁之前调用带注释的方法。
Java 程序显示注释配置的用法以控制注释的使用。
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class DemoBean
{
@PostConstruct
public void customInit()
{
System.out.println("Method customInit() invoked...");
}
@PreDestroy
public void customDestroy()
{
System.out.println("Method customDestroy() invoked...");
}
}
所以这就是 Spring 容器内的 Spring bean 生命周期。记住上面给出的所有类型的生命周期事件,这是一个常见的Spring面试问题。
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/243948.html