6、IOC 之自定义Bean属性

6、IOC 之自定义Bean属性

Spring框架提供了许多接口,您可以使用它们来自定义 Bean 的性质。本部分将它们分组如下:

6.1、生命周期回调

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

JSR-250 @PostConstruct@PreDestroy注释通常被认为是在现代 Spring 应用程序中接收生命周期回调的最佳实践。使用这些注释意味着您的 Bean 不会耦合到特定于 Spring 的接口。有关详细信息,请参阅使用 @PostConstruct@PreDestroy

如果不想使用 JSR-250 注释,但仍要删除耦合,请考虑 init-methoddestroy-method 来定义 Bean 元数据。

① 初始化回调

org.springframework.beans.factory.InitializingBean

该接口允许 Bean 在容器上设置了所有必要的属性后执行初始化工作

package org.springframework.beans.factory;
public interface InitializingBean {
	void afterPropertiesSet() throws Exception;
}

◆ 注意点:

  • 官方不建议使用该回调接口,因为它会不必要地将代码耦合到Spring

  • 建议使用 @PostConstruct 注释或指定 POJO 初始化方法

    • 对于基于 XML 的配置元数据,可以使用 init-method 属性指定具有 void 无参数签名的方法的名称
    • 使用 Java 配置,可以使用@BeaninitMethod属性
      在这里插入图片描述

② 销毁回调

org.springframework.beans.factory.DisposableBean

实现该接口允许 Bean 在包含它的容器被销毁时获得回调

package org.springframework.beans.factory;
public interface DisposableBean {
	void destroy() throws Exception;
}

◆ 注意点:

  • 官方不建议使用该回调接口,因为它不必要地将代码耦合到Spring
  • 建议使用@PreDestroy 注释或指定 Bean 定义支持的泛型方法
    • 对于基于 XML 的配置元数据,可以使用 <bean/> 上的destroy-method 属性
    • 使用 Java 配置,可以使用 @BeandestroyMethod属性
      在这里插入图片描述

③ 默认初始化和销毁方法

相当于定义一个初始化和销毁的规范。

比如 <beans/> 里所有bean类内都定义了(有就调没有就拉倒)初始化和销毁方法都叫 init()destroy(),这样我们就可以使用 <beans/> 的两个属性: default-init-method="init"default-destroy-method="destroy"

<beans default-init-method="init" default-destroy-method="destroy">
    <bean id="blogService" class="com.xxx.DefaultBlogService"/>
    <bean id="otherService" class="com.xxx.OtherService"/>
</beans>

④ 组合生命周期机制

从 Spring 2.5 开始,您有三个选项来控制 Bean 生命周期行为:

如果为 Bean 配置了多个生命周期机制,并且每个机制都配置了不同的方法名称,则每个配置的方法将按本说明之后(下面)列出的顺序运行。但是,如果为多个这些生命周期机制配置了相同的方法名称(例如,初始化方法 init()),则该方法将运行一次,如上一节所述。

1、为同一 Bean 配置的具有不同初始化方法的多个生命周期机制的调用方式如下:

  1. @PostConstruct 注释的方法
  2. 由回调接口 InitializingBean 定义的 afterPropertiesSet()
  3. 自定义配置的 init() 方法

2、销毁方法的调用顺序相同:

  1. @PreDestroy 注释的方法
  2. 由回调接口 DisposableBean 定义的 destroy()
  3. 自定义配置的 destroy() 方法

④ 启动和关闭回调

该接口为具有自己的生命周期要求(例如启动和停止某些后台进程)的任何对象定义了基本方法:Lifecycle

package org.springframework.context;
public interface Lifecycle {
	void start();
	void stop();
	boolean isRunning();
}

任何 Spring 管理的对象都可以实现该接口。然后,当自身接收到启动和停止信号(例如,对于运行时的停止/重新启动方案)时,它会将这些调用级联到该上下文中定义的所有实现。

package org.springframework.context;
public interface LifecycleProcessor extends Lifecycle {
	void onRefresh();
	void onClose();
}

请注意,LifecycleProcessor本身是Lifecycle接口的扩展。它还添加了另外两种方法,用于对正在刷新和关闭的上下文做出反应。

其余内容可直接访问 官方文档

⑤ 在非 Web 应用程序中优雅地关闭春季 IoC 容器

本小节内容可直接访问 官方文档

6.2、ApplicationContextAwareBeanNameAware

ApplicationContext 创建实现 org.springframework.context.ApplicationContextAware 接口的对象实例时,将为该实例提供对该 ApplicationContextAware 的引用。

package org.springframework.context;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

因此,bean 可以通过 ApplicationContext 接口或通过将引用转换为该接口的已知子类(例如 ConfigurableApplicationContext,它公开附加功能)以编程方式操作创建它们的 ApplicationContext。一种用途是对其他 bean 进行编程检索。有时,此功能很有用。但是,通常应该避免使用它,因为它将代码与 Spring 耦合,并且不遵循 IoC,其中协作者作为属性提供给 bean。 ApplicationContext 的其他方法提供对文件资源的访问、发布应用程序事件和访问 MessageSource。这些附加功能在 ApplicationContext 的附加功能中进行了描述。

从 Spring 2.5 开始,自动装配是获取 ApplicationContext 引用的另一种方法。 “传统”构造函数和 byType 自动装配模式(如 Autowiring Collaborators 中所述)可以分别为构造函数参数或 setter 方法参数提供 ApplicationContext 类型的依赖关系。要获得更大的灵活性,包括自动装配字段和多个参数方法的能力,请使用新的基于注释的自动装配功能。如果这样做,ApplicationContext 将自动装配到需要 ApplicationContext 类型的字段、构造函数参数或方法参数中,前提是相关字段、构造函数或方法带有 @Autowired 注释。

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

package org.springframework.beans.factory;
public interface BeanNameAware extends Aware {
	void setBeanName(String name);
}

在填充正常的bean属性之后,但在初始化回调(例如InitializingBean.afterPropertiesSet或自定义init-method)之前,调用该回调。

6.3、其他 Aware 接口

除了ApplicationContextAwareBeanNameAware 之外,Spring还提供了多种Aware回调接口,这些接口使Bean向容器指示它们需要某种基础结构依赖性。 通常,名称表示依赖项类型。 下表总结了最重要的Aware接口:

NameInjected DependencyExplained in…
ApplicationContextAware声明 ApplicationContextApplicationContextAwareBeanNameAware
ApplicationEventPublisherAware封闭 ApplicationContext 的事件发布者ApplicationContext 的其他功能
BeanClassLoaderAware用于加载 Bean 类的类加载器实例化Bean
BeanFactoryAware声明 BeanFactoryBeanFactory API
BeanNameAware声明 Bean 的名称ApplicationContextAwareBeanNameAware
LoadTimeWeaverAware定义了用于在加载时处理类定义的编织器在Spring框架中使用AspectJ进行加载时间编织
MessageSourceAware已配置的消息解析策略(支持参数化和国际化)ApplicationContext 的附加功能
NotificationPublisherAwareSpring JMX 通知发布者通知
ResourceLoaderAware为资源的低级访问配置了加载器资源
ServletConfigAware容器运行的当前 ServletConfig。仅在web感知的Spring ApplicationContext中有效Spring MVC
ServletContextAware容器运行的当前 ServletContext。仅在web感知的Spring ApplicationContext中有效Spring MVC

再次注意,使用这些接口会将你的代码与Spring API绑定在一起,并且不遵循IOC。 官方建议将它们用于需要以编程方式访问容器的基础结构 Bean。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯纯的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值