Spring 中的Aware接口有什么作用

news2024/11/26 15:25:01

文章目录

  • 0.前言
  • 1.什么是Aware接口
  • 2.Aware接口的设计目的
  • 3.详解
    • 3.1. `ApplicationContextAware`
      • 我们举个例子来说明
    • 3.2. `BeanFactoryAware`
    • 3.3. `BeanNameAware`
    • 3.4. `ServletContextAware`
    • 3.5. `MessageSourceAware`
    • 3.6. `ResourceLoaderAware`
  • 4.参考文档

在这里插入图片描述

0.前言

背景: 最近有开发同学问我项目里面有很多地方实现了Aware 接口,到底是什么作用。他说这个原因是在我们的工程代码中看到有一些代码里实现了ResourceLoaderAware、BeanNameAware、ApplicationContextAware、BeanFactoryAware接口。我没法直接笼统回答,也没有法一句话简答,只好侧面的告诉他Aware接口是Spring 为了提供拓展的一种设计思想。凡是带Aware后缀的接口。主要作用是为了让实现了该接口的Bean在Spring容器中具有回调功能。通过实现不同子接口,可以让Bean在运行过程中获取Spring容器内部的一些特定对象

为了进一步论证我给的答案,今天抽时间把项目里面的Aware的实现或者间接实现的类大概看了一下。包含Spring框架和第三方框架在内,大概有673个实现使用到。
在这里插入图片描述

Spring Boot Actuator 是一个强大的监控和管理框架,它提供了一系列的监控端点,可以用于获取应用程序的状态、度量指标、健康检查、配置信息等。Actuator 的监控端点可以通过 HTTP 请求访问,并返回有关应用程序运行时信息的响应。

使用 Actuator 可以方便地了解应用程序的运行状况,监控关键指标,并根据需要采取相应的措施。它为开发人员和运维人员提供了一种简单而有效的方式来监控和管理 Spring Boot 应用程序。

本系列文章将深入探讨 Spring Boot Actuator 监控端点的各个方面。我们将逐个介绍默认的监控端点,包括健康检查、信息、度量指标等,并说明如何自定义和扩展这些端点以满足特定需求。

在本系列文章中,你将学到以下内容:

  1. Actuator 的介绍和基本概念。
  2. 默认监控端点的详细解释,包括健康检查、信息、度量指标等。
  3. 如何自定义监控端点,以便获取特定的应用程序状态和信息。
  4. 监控端点的安全性配置,以保护敏感信息的访问。
  5. 如何使用 Actuator 的事件和监听器功能。
  6. Actuator 的扩展性机制,包括自定义指标、自定义端点和自定义 EndpointGroup 等。

通过阅读本系列文章,你将全面了解 Spring Boot Actuator 监控端点的功能和用法,能够灵活应用 Actuator 来监控和管理你的 Spring Boot 应用程序。让我们开始这个有趣而实用的学习之旅吧!

1.什么是Aware接口

我们先来看一下所有Aware接口的超接口的定义org.springframework.beans.factory.Aware
在这里插入图片描述
根据注释我们可以了解到 org.springframework.beans.factory.Aware 标记超接口,指示一个Bean有资格通过回调方式接收Spring容器传递的特定框架对象。实际的方法签名由各个子接口决定,但通常应该只包含一个接受单一参数的返回void的方法。这个翻译有点抽象 通俗的说 这个Aware接口是Spring框架中的一个机制,允许Bean通过回调方式与Spring容器进行交互,并获取特定的框架对象,以便在Bean的逻辑中进行相应的处理

Spring框架中有一系列的Aware接口,这些接口是用于让实现它们的Bean获得一些Spring框架的对象或资源,这些资源包括ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher等等。

Aware接口名称通常是以Aware结尾,例如最常见的ApplicationContextAware和BeanFactoryAware,它们分别可以让Bean获得ApplicationContext和BeanFactory。

例如,如果一个Bean实现了ApplicationContextAware接口,那么在Spring创建这个Bean的时候,会自动调用setApplicationContext方法,将ApplicationContext作为参数传入,这样这个Bean就可以在运行时获取到Spring的ApplicationContext。

通常并不建议直接使用Aware接口,因为这样会导致代码与Spring框架耦合过于紧密。在大多数情况下,我们可以通过依赖注入或者其他更好的方式来获取Spring框架的资源。除非为了实现特定功能,我们才会实现对应的Aware接口来获取资源。

2.Aware接口的设计目的

这样设计的目的是为了让Bean可以与Spring框架的其他部分相互作用,而不是仅仅被动地接受由Spring容器创建和管理。

我觉得这样的设计 还有一个好处 。可以直接通过名称+Aware后缀就可以知道这个Aware接口具备的能力。可以直接获取或操作Spring框架的一些资源,换句话来讲,其实也是Spring的格局比较高 使得Spring框架“让普通Java对象能够使用框架的全功能”的一种体现。

所以,通常来说,接口名的规则是:[感知/获得的资源或环境] + Aware例如BeanFactoryAwareResourceLoaderAware
在这里插入图片描述

我们观察一下Aware接口及其子接口的命名规则很简单,通常是在Aware后面添加相应的功能名。这些功能名通常代表了实现该接口的类需要获得的资源或者感知的环境。例如:

  • ApplicationContextAware:意味着实现该接口的类可以感知到应用上下文(ApplicationContext)。

  • BeanFactoryAware:实现该接口的类可以感知到Bean工厂(BeanFactory)。

  • BeanNameAware:实现该接口的类可以感知到Bean的名字。

  • ServletContextAware意味着实现该接口的类可以感知到Servlet上下文(ServletContext)。

  • MessageSourceAware:实现该接口的类可以感知到消息源(MessageSource)。

-ResourceLoaderAware:实现该接口的类可以感知到资源加载器(ResourceLoader)。

3.详解

我们分别来了解一下这些常见的Aware接口的使用场景和用法 ApplicationContextAwareBeanFactoryAwareBeanNameAwareServletContextAwareMessageSourceAwareResourceLoaderAware

3.1. ApplicationContextAware

这个接口我们太常见了。几乎大多数项目中都会用到。因为它能取到。它会在一个类需要访问Spring应用上下文中的所有服务(例如其他bean,生命周期事件,特定配置等)时被实现。

ApplicationContextAware 是 Spring 框架的一个接口,当一个类实现了这个接口,那么这个类就会具备访问 Spring ApplicationContext 的能力。也就是说,这个类可以直接获取到 spring 容器中的所有 bean。

这个接口主要有一个方法:setApplicationContext(ApplicationContext applicationContext)。Spring 容器会检测所有 bean,如果发现某个 bean 实现了 ApplicationContextAware 接口,Spring 容器就会在创建该 bean 后,自动调用这个 bean 的 setApplicationContext(ApplicationContext applicationContext) 方法,调用该方法时,会将容器本身作为参数传给该 bean。这样,当 bean 需要使用容器的功能时,就可以使用这个传入的参数。

这个接口通常在需要访问容器本身的功能,或者需要访问容器中的其他 bean 时使用。例如,当 bean 需要动态地查找其他 bean,或者需要使用容器的发布事件功能时,就可以通过实现这个接口来获取到容器对象。

一般情况下,我们不需要直接实现这个接口,因为 Spring 提供了 ApplicationObjectSupport 类,这个类实现了 ApplicationContextAware 接口,我们可以通过继承这个类来简化我们的代码。

我们举个例子来说明

下面是一个具体的计算服务示例,它使用 ApplicationContextAware 接口来获取一个账户服务。
CalculationService 类实现了 ApplicationContextAware 接口,并重写了 setApplicationContext 方法。当 Spring 容器创建 CalculationService 实例之后,就会自动调用 CalculationServicesetApplicationContext 方法,并将容器本身作为参数传入。
然后,CalculationService 就可以通过 applicationContext 成员变量来访问容器本身,从而获取到容器中的 AccountService,并使用该服务来进行利息计算。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class CalculationService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public double calculateInterest(String accountId, double principal, double rate, double time) {
        // 通过 applicationContext 获取 Spring 容器中的 AccountService bean
        AccountService accountService = applicationContext.getBean(AccountService.class);
        // 使用获取到的 AccountService 进行操作
        double interest = accountService.calculateInterest(principal, rate, time);
        return interest;
    }
}

3.2. BeanFactoryAware

当一个类需要访问Spring BeanFactory,以获得对Spring框架的底层访问时,会实现这个接口。

我们举个例子来理解一下,比如我们大多项目都会发送通知,可能需要邮件,微信,短信,飞书这些,这些配置可以允许用户自定义配置,后续系统还可能扩展钉钉等其他类型通知。为了满足这个需求。我们利用 BeanFactoryAware 创建一个服务定位器(Service Locator)。服务定位器用于集中管理和查找服务。在复杂的应用中,这可以使代码更容易管理和扩展。

首先考虑我们有许多服务,如 EmailServiceSMSServicePushNotificationService 等,都实现了一个 MessageService 接口。我们可以使用 BeanFactoryAware 来创建一个服务定位器,能够根据需要获取任何服务。

@Service
public class ServiceLocator implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public MessageService getService(String serviceName) {
        return (MessageService) beanFactory.getBean(serviceName);
    }
}

然后在需要服务的地方,我们可以这样使用:

@Service
public class MessageClient {

    private final ServiceLocator serviceLocator;

    public MessageClient(ServiceLocator serviceLocator) {
        this.serviceLocator = serviceLocator;
    }

    public void sendMessage(String message, String serviceName) {
        MessageService service = serviceLocator.getService(serviceName);
        service.send(message);
    }
}

ServiceLocator 通过实现 BeanFactoryAware 接口,可以获取到 Spring 容器,然后根据服务名获取相应的服务。MessageClient 通过 ServiceLocator 可以灵活地选择需要的服务,使得代码更加灵活和可测试。

剩下这四个也很常见,明天有时间再搞吧,今天太晚了就到这

3.3. BeanNameAware

当一个类需要知道在Spring配置中定义的它的bean名称时,会实现这个接口。

3.4. ServletContextAware

这个接口会在一个类需要获取到ServletContext,通常用在需要访问Servlet API的web应用中时被实现。例如,需要读取web应用中的某些real path,或者servlet context attributes等。

3.5. MessageSourceAware

当一个类需要加载一些消息资源,如一些国际化的字符串时,会实现这个接口。

3.6. ResourceLoaderAware

当一个类需要加载一些文件资源时,会实现这个接口。这可以让你更方便的加载classpath或者文件系统中的资源。

4.参考文档

  1. Spring 官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-aware
  2. Spring 框架 API 文档(有关 BeanFactoryAware 的部分):https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/BeanFactoryAware.html
  3. 关于服务定位器模式的解释:https://www.martinfowler.com/eaaCatalog/serviceLocator.html
  4. 使用 Spring 实现服务定位器模式的示例:https://www.baeldung.com/spring-service-locator

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7完全离线环境安装Nvidia Tesla A100 40G显卡驱动(含CUDA Toolkit)和Anaconda3虚拟环境

公司一台完全离线环境的服务器刚装了Nvidia Tesla A100 40G显卡,自己摸索着将显卡驱动在完全离线环境下安装成功,这里记录一下。 一、下载Centos7适配的Nvidia Tesla A100 40G显卡驱动 在Nvidia官网下载Centos7适配的显卡驱动,CUDA Toolkit…

idea(第一次)启动项目,端口变成了8080

先上配置 server:port: 9569 spring:profiles:active: dev 该排查的问题也都没问题,重启idea也试过了,还是8080 解决办法:点击右侧的maven ,左上角的重新导入 reimport all maven projects 我又没有改动pom文件,居然还要点这…

玩机教程:阿里云无影云电脑怎么使用?

阿里云无影云电脑即无影云桌面,云电脑如何使用?云电脑购买后没有用户名和密码,先创建用户设置密码,才可以登录连接到云桌面。云桌面想要访问公网还需要开通互联网访问功能。阿里云百科来详细说下阿里云无影云电脑从购买、创建用户…

Android 13.0 SystemUI下拉状态栏背景增加高斯模糊背景

1.概述 在13.0的产品开发中,发现现在很多产品都是高斯模糊背景的,这种高斯模糊背景看起来效果很不错,产品开发需要SystemUI下拉状态栏背景也是高斯模糊背景,所以就要来实现下拉状态栏高斯模糊背景 2.SystemUI 下拉状态栏背景增加高斯模糊背景核心类 frameworks/base/pack…

python后端和前端通过websocket通讯发消息最小案例,十分钟看懂

前端和后端通过websocket实现发送消息案例,用于理解websocket,服务端可以主动给客户端发送消息,而且是长连接,比http效率高,因为http要不断地创建和销毁socket实例,导致压力很大。websocket一次创建&#x…

自定义类型:结构体----初学者笔记

目录 1. 结构体类型的声明 1.1 结构体类型的简单介绍和声明 1.1.1 结构的声明 1.1.2 特殊的声明 1.1.3 结构的自引用 2. 结构体变量的创建和初始化 3. 结构成员访问操作符 4. 结构体内存对⻬ 4.1 对齐规则 4.2 练习 4.2.1 练习1 4.2.2 练习2 4.3 为什么存在内存对…

知名IT网站博客园陷入绝境

我是卢松松,点点上面的头像,欢迎关注我哦! 博客园陷入生死存亡的绝境。 5月份知名IT开发者网站发布文章称“博客园网站遇到困难了:寻求捐助”,并开通了捐助渠道。4个月过去了,好像效果并不明显&#xff…

婚庆行业类软文怎么写?媒介盒子无偿分享

随着我国经济发展以及对婚礼品质要求的提升,结婚相关的市场发展愈发强劲,由于互联网发展的快速性,大部分新人选择通过网络获取结婚服务信息,所以线上成为婚庆公司的主要获客渠道。而软文营销就是婚庆公司提升品牌形象的主要方式&a…

AI写作工具,智能ai写作工具

在信息化时代,内容创作已经成为了许多行业的核心。从营销广告到新闻报道,从博客文章到学术论文,人们需要不断地产生高质量的文字内容。创作是一项耗时耗力的工作,需要丰富的知识和创造性思维。 AI写作工具,是一类基于人…

docker容器技术实战-3

08 docker 原生网络 原生网络:桥接模式 :生成虚拟网络对 host模式:容器和宿主机共享同一网络栈,不会新建虚拟网卡 none禁用网络:只用回环接口 自定义接口:内嵌dns解析 不同网络之间是被隔离的,默认不能通…

【C++】map与set的封装

文章目录 前言正文1. 类型的泛化2.仿函数3.迭代器3.1正向迭代器3.1.1 3.1.2 - -3.1.3 *3.1.4 ->3.1.5 !完整版代码 4.[](map) 框架1.红黑树2.set3.map 总结 前言 在学习了红黑树之后,我们便可以尝试初步的在红黑树的基础上封装出map与set&…

Python日志处理器,同时打印到控制台和保存到文件中,并保证格式一致

使用logging模块的时候,默认是输出到控制台的,当然也可以配置输出到文件中,但是当你配置了文件后,控制台的输出就消失了,所以,需要一个策略即能保存到文件中,又能输出到控制台中。 下面是我做的…

ORB-SLAM2实时稠密地图,解决运行报段错误(核心已转储)运行数据集时出现段错误,出现可视化界面后闪退(添加实时彩色点云地图+保存点云地图)

高翔的稠密建图仓库 1. git clone https://github.com/gaoxiang12/ORBSLAM2_with_pointcloud_map.git 2. 去ORB SLAM2里拷贝Vocabulary到/home/cgm/ORBSLAM2_with_pointcloud_map/ORB_SLAM2_modified文件夹下 3. 删除一些build文件夹 删除ORB_SLAM2_modified/Thirdparty/DB…

国产手机芯片4G方案_紫光展锐安卓核心板虎贲4G智能模块方案定制

元器件清单即BOM物料清单,不同行业领域的BOM表侧重点不一样。安卓主板的BOM表则侧重点在于元器件物料的清单,也就是安卓电路板的PCBA清单,精密的安卓板有上千个物料,可以帮助我们估算物料成本,建立生产计划&#xff0c…

Ftp服务器、 Samba服务器、NFS服务器的区别

根据使用的方式来看,可以分为3种类别的文件服务器:ftp服务器(ftp/tftp)、 Samba服务器、NFS服务器。ftp的客户可以是任意平台,samba是专门针对windows客户,而NFS则是面向linux/unix用户的。下面是三种服务器…

CRM软件系统价格不同的原因

很多人在了解CRM系统时,发现不同品牌的CRM价格有着很大的区别。一些CRM系统只需要几千块钱,一些CRM系统的报价却要上万,甚至十几万。为什么CRM系统价格不同?下面我们就来说说。 1、功能不同 从功能方面来说,一些CRM系…

OpenCV Series : Slope + Radian + Degree

def lineSlope(p1, p2):slope (p2[1] - p1[1]) / (p2[0] - p1[0])return slopedef slopeAngle(p1, p2):slope lineSlope(p1, p2)radian np.arctan(slope)return radiandef angleDegree(radian):theta int(radian * 180 / np.pi) % 360return theta

【LeetCode热题100】--3.无重复字符的最长子串

3.无重复字符的最长子串 使用滑动窗口: 使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着枚举字串的起始位置,而右指针即为 r k r_k rk​在每一步操作中,我们会将左指针向右移动一…

Python类练习

文章目录 题目要求步骤 题目要求 1)创建一个 Kid 类,包含姓名,性别,年龄属性和 play 方法 2) 创建一个 Stu 类,继承 Kid 类,同时包含成绩属性,获取成绩方法,努力学习方法,play方法&…

RocketMQ核心编程模型以及生产环境最佳实践

⼀、回顾 RocketMQ 的消息模型 ⼆、深⼊理解 RocketMQ 的消息模型 1 、 RocketMQ 客户端基本流程 RocketMQ 基于 Maven 提供了客户端的核⼼依赖: 使⽤客户端进⾏编程时,添加这⼀个核⼼依赖就够了。 另外还有⼀个与权限控制相关的核⼼依赖也需要了解。尽…