换我心,为你心,始知相忆深。
在本章中,我们学习 Spring bean
的生命周期。掌握 bean
生命周期的各个阶段,初始化和销毁回调方法。我们将学习使用 XML
配置和注释配置来控制 bean
生命周期事件。
当容器启动时–-需要基于 Java
或 XML
bean
定义实例化 Spring bean
。还需要执行一些初始化后的步骤,以使其进入可用状态。 Spring Boot
启动应用程序也具有相同的 bean
生命周期。
之后,当不再需要该 bean
时,它将被从 IoC
容器中删除。
Spring bean
factory
负责管理通过 Spring
容器创建的 bean
的生命周期。
Spring bean
factory
控制 bean
的创建和销毁。为了执行一些自定义操作,它提供了回调方法,这些方法可以大致分为两类:
Post-initialization Pre-destruction
Spring
框架提供了以下4种方法来控制 Bean
的生命周期事件:
InitializingBean
和 DisposableBean
回调接口 *Aware
接口提供一些特殊的实现 Bean
配置文件中的自定义 init()
和 destroy()
方法 @PostConstruct
和 @PreDestroy
注解 InitializingBean
和 DisposableBean
接口 org.springframework.beans.factory.InitializingBean
接口允许 bean
在容器设置了 bean
的所有必要属性之后执行初始化工作。
InitializingBean
接口指定一个方法:
void afterPropertiesSet() throws Exception;
这并不是初始化 bean
的首选方法,因为它将 bean
类与 spring
容器紧密地耦合在一起。更好的方法是在 applicationContext.xml
文件的 bean
定义中使用 init-method
属性。
类似地,实现 org.springframework.beans.factory.DisposableBean
接口允许 Bean
在包含它的容器被销毁时获得回调。
DisposableBean
接口指定一个方法:
void destroy() throws Exception; // 实现上述接口的示例bean: package cn.howtodoinjava.task; 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 } }
*Aware
接口 Spring
提供了一系列 *Aware
接口,允许 bean
向容器表明它们需要某种基础设施依赖。每个接口都需要您实现一个方法来将依赖项注入 bean
。
这些接口可以概括为:
*Aware 接口 |
重写方法 | 目的 |
---|---|---|
ApplicationContextAware |
void setApplicationContext (ApplicationContext applicationContext) throws BeansException; |
接口将由任何希望将其运行的 ApplicationContext 通知给它的对象来实现。 |
ApplicationEventPublisherAware |
void setApplicationEventPublisher (ApplicationEventPublisher applicationEventPublisher); |
设置此对象运行的 ApplicationEventPublisher 。 |
BeanClassLoaderAware |
void setBeanClassLoader (ClassLoader classLoader); |
将 bean 类加载器提供给 bean 实例的回调。 |
BeanFactoryAware |
void setBeanFactory (BeanFactory beanFactory) throws BeansException; |
将拥有的工厂提供给 Bean 实例的回调。 |
BeanNameAware |
void setBeanFactory (BeanFactory beanFactory) throws BeansException; |
在创建此 bean 的 bean 工厂中设置 bean 的名称。 |
BootstrapContextAware |
void setBootstrapContext (BootstrapContext bootstrapContext); |
设置该对象在其中运行的 BootstrapContext 。 |
LoadTimeWeaverAware |
void setLoadTimeWeaver (LoadTimeWeaver loadTimeWeaver); |
设置此对象包含 ApplicationContext 的 LoadTimeWeaver 。 |
MessageSourceAware |
void setMessageSource (MessageSource messageSource); |
设置此对象在其中运行的 MessageSource 。 |
NotificationPublisherAware |
void setNotificationPublisher (NotificationPublisher notificationPublisher); |
为当前的托管资源实例设置 NotificationPublisher 实例。 |
PortletConfigAware |
void setPortletConfig (PortletConfig portletConfig); |
设置运行该对象的 PortletConfig 。 |
PortletContextAware |
void setPortletContext (PortletContext portletContext); |
设置此对象在其中运行的 PortletContext 。 |
ResourceLoaderAware |
void setResourceLoader (ResourceLoader resourceLoader); |
设置此对象在其中运行的 ResourceLoader 。 |
ServletConfigAware |
void setServletConfig (ServletConfig servletConfig); |
设置运行该对象的 ServletConfig 。 |
ServletContextAware |
void setServletContext (ServletContext servletContext); |
设置运行该对象的 ServletContext 。 |
下面的 Java
代码块展示了使用 *Aware
接口 来控制 bean
生命周期的用法。
package cn.howtodoinjava.task; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.weaving.LoadTimeWeaverAware; import org.springframework.core.io.ResourceLoader; import org.springframework.instrument.classloading.LoadTimeWeaver; import org.springframework.jmx.export.notification.NotificationPublisher; import org.springframework.jmx.export.notification.NotificationPublisherAware; public class DemoBean implements ApplicationContextAware, ApplicationEventPublisherAware, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, LoadTimeWeaverAware, MessageSourceAware, NotificationPublisherAware, ResourceLoaderAware { @Override public void setResourceLoader(ResourceLoader arg0) { // TODO Auto-generated method stub } @Override public void setNotificationPublisher(NotificationPublisher arg0) { // TODO Auto-generated method stub } @Override public void setMessageSource(MessageSource arg0) { // TODO Auto-generated method stub } @Override public void setLoadTimeWeaver(LoadTimeWeaver arg0) { // TODO Auto-generated method stub } @Override public void setBeanName(String arg0) { // TODO Auto-generated method stub } @Override public void setBeanFactory(BeanFactory arg0) throws BeansException { // TODO Auto-generated method stub } @Override public void setBeanClassLoader(ClassLoader arg0) { // TODO Auto-generated method stub } @Override public void setApplicationEventPublisher(ApplicationEventPublisher arg0) { // TODO Auto-generated method stub } @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { // TODO Auto-generated method stub } }
init()
和 destroy()
方法 bean
配置文件中的默认 init
和 destroy
方法有两种定义方法:
Bean
的 Bean
本地定义 bean
上下文中定义的所有 bean
Bean
本地定义 本地定义如下:
<beans> <bean id="demoBean" class="com.howtodoinjava.task.DemoBean" init-method="customInit" destroy-method="customDestroy"></bean> </beans>
全局定义如下,这些方法将为 <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>
Java
程序代码示例:
package cn.howtodoinjava.task; public class DemoBean { public void customInit() { System.out.println("Method customInit() invoked..."); } public void customDestroy() { System.out.println("Method customDestroy() invoked..."); } }
@PostConstruct
和 @PreDestroy
注解 从 Spring 2.5
开始,你还可以使用注解通过 @PostConstruct
和 @PreDestroy
注解指定生命周期方法。
@PostConstruct
注解的方法将在使用默认构造函数构造 bean
之后调用,并在它的实例返回给请求对象之前调用。 @PreDestroy
注解方法在 bean
即将在 bean
容器中销毁之前被调用。 Java
代码示例如下:
package cn.howtodoinjava.task; 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
面试中经常问到的问题。
关注微信公众号 java干货 不定期分享干货资料
原文链接: Spring 5 – Bean scopes