Spring5核心原理-Bean的生命周期

了解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 工厂提供了回调方法,大致可以分为两类:
 

  1. 初始化后回调方法
  2. 预销毁回调方法
Spring-bean-life-cycle
Spring-bean-life-cycle

2. 如何自定义 Bean 生命周期

Spring框架提供了以下四种方式来控制和实现一个bean的生命周期事件:

  1. InitializingBeanDisposableBean回调接口
  2. *特定行为的感知接口
  3. bean配置文件中的自定义init()和方法destroy()
  4. @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

(0)
上一篇 2022年4月11日 22:20
下一篇 2022年4月11日 22:20

相关推荐

发表回复

登录后才能评论