项目实训 12 学习Spring(6)

226 阅读5分钟

1.6:自定义bean的性质:

Spring 框架提供了许多接口,可用于自定义 Bean 的性质。

1.6.1:生命周期回调:

要让容器对bean生命周期进行交互,可以实现Spring InitializingBean和DisposableBean接口。容器对前者调用afterPropertiesSet(),对后者调用destroy(),以使Bean在初始化和销毁Bean时执行某些操作。

在内部,Spring 框架使用BeanPostProcessor实现来处理它可以找到的任何回调接口并调用适当的方法。如果您需要自定义功能或其他生命周期行为,Spring 默认不提供,则您可以自己实现BeanPostProcessor。

Initialization Callbacks:

InitializingBean接口指定一个方法:

image.png

image.png

但建议不使用实现该接口的方法来进行初始化操作,因为它不必要地将代码耦合到了Spring。

我们建议使用@PostConstruct注解或指定 POJO 初始化方法。对于基于 XML 的配置元数据,可以使用init-method属性指定具有无效无参数签名的方法的名称。通过 Java 配置,可以使用@Bean的initMethod属性。

例:

image.png

Destruction Callbacks:

DisposableBean接口指定一个方法:

image.png

image.png

建议使用@PreDestroy注解或指定 bean 定义支持的通用方法。使用基于 XML 的配置元数据时,可以在上使用destroy-method属性。通过 Java 配置,可以使用@Bean的destroyMethod属性。

例:

image.png

默认初始化和销毁方法:

可以在顶层元素属性上的default-init-method和default-destroy-method设置初始化和销毁方法回调。便可以使得beans中的每个bean都采用这策略(即初始化方法名称一致)。

但可以通过使用本身的init-method和destroy-method属性指定(在 XML 中)方法名称来覆盖默认值。

例:

image.png

image.png

Spring 容器保证在为 bean 提供所有依赖项后立即调用配置的初始化回调。

组合生命周期机制:

如果为一个 bean 配置了多个生命周期机制,并且为每个机制配置了不同的方法名称,则将按照此注解后列出的执行每个已配置的方法。但是,如果为多个生命周期机制中的多个生命周期配置了相同的方法名称,则该方法将执行一次.

有三种控制bean的方法:

InitializingBean和DisposableBean回调接口

自定义init()和destroy()方法

@PostConstruct 和@PreDestroy 注解。您可以结合使用这些机制来控制给定的 bean。

启动和关闭回调:

Lifecycle接口提供了当启动或关闭时的操作。

image.png

任何 SpringManagement 的对象都可以实现Lifecycle接口。然后,当ApplicationContext本身接收到启动和停止 signal 时(例如,对于运行时的停止/重新启动场景),它将把这些调用级联到在该上下文中定义的所有Lifecycle实现。

LifecycleProcessor接口是Lifecycle接口的扩展。它还添加了两种其他方法来响应正在刷新和关闭的上下文。

image.png

常规org.springframework.context.Lifecycle接口是用于显式启动和停止通知的普通协议,并不意味着在上下文刷新时自动启动。为了对特定 bean 的自动启动进行精细控制(包括启动阶段),请考虑实现org.springframework.context.SmartLifecycle。

注意,不能保证会在销毁之前发出停止通知。在常规关闭时,在传播常规销毁回调之前,所有Lifecycle bean 都首先收到停止通知。但是,在上下文生存期内的热刷新或中止的刷新尝试中,仅调用 destroy 方法。

启动和关闭调用的序列可能很重要。因为例在一对bean中,beanA依赖于beanB,则beanA应该在beanB之后启动,在beanB之前关闭。但是,有时直接依赖项是未知的。您可能只知道某种类型的对象应该先于另一种类型的对象开始。在这些情况下,SmartLifecycle接口定义了另一个选项,即在其超级接口Phased上定义的getPhase()方法。

phased接口的定义:

image.png

smartLifecycle接口的定义:

image.png

启动时,相位最低的对象首先启动。停止时,遵循相反的序列。

因此,实现SmartLifecycle且其getPhase()方法返回Integer.MIN_VALUE的对象将是第一个启动且最后一个停止的对象。相位值Integer.MAX_VALUE表示该对象应最后启动并首先停止。重要的是要知道,任何未实现SmartLifecycle的Lifecycle对象的默认相位是0。因此,任何负相位值都表明对象应在这些标准组件之前开始(并在它们之后停止)。对于任何正相位值,反之亦然。

LifecycleProcessor接口的默认实现DefaultLifecycleProcessorawait 每个阶段内的对象组的超时值,以调stop回调。您可以通过在上下文中定义一个名为lifecycleProcessor的 bean 来覆盖默认的生命周期处理器实例。修改超时例子:

image.png

LifecycleProcessor接口还定义了用于刷新和关闭上下文的回调方法。后者驱动关闭过程,能在上下文关闭时发生尽管没有明确表示关闭。“刷新”回调启用SmartLifecycle bean 的另一个功能。刷新上下文时(在所有对象都被实例化和初始化之后),该回调将被调用。那时,默认生命周期处理器将检查每个SmartLifecycle对象的isAutoStartup()方法返回的布尔值。如果true,则在该点启动该对象,而不是等待上下文或它自己的start()方法的显式调用(与上下文刷新不同,对于标准的上下文实现,上下文启动不会自动发生)。 phase值和任何“依赖”关系来确定启动的序列。

在非web应用程序中正常关闭Spring IoC容器:

如果您在非 Web 应用程序环境中(例如,在富 Client 端桌面环境中)使用 Spring 的 IoC 容器,请向 JVM 注册一个关闭钩子。这样做可以确保正常关机,并在您的 Singleton bean 上调用相关的 destroy 方法,以便释放所有资源。您仍然必须正确配置和实现这些 destroy 回调。

image.png

1.6.2:ApplicationContextAware和BeanNameAware:

当ApplicationContext创建实现org.springframework.context.ApplicationContextAware接口的对象实例(bean)时,该实例(bean)将获得对该ApplicationContext的引用。

一种用途是通过编程方式检索其他 bean。

当ApplicationContext创建实现org.springframework.beans.factory.BeanNameAware接口的类时,该类将获得对在其关联的对象定义中定义的名称的引用。