Spring framework Day22:Aware接口

前言

在Spring框架中,有许多接口和类都有一个非常重要的作用——让我们能够更方便地构建应用程序和管理组件。其中,Aware接口就是其中一个非常重要的接口之一。通过实现该接口,我们可以让Spring容器感知到特定的组件和资源,并进行初始化或注入。本文将介绍Aware接口的概念、使用方法以及示例。

一、什么是 Aware 接口

Aware接口是Spring框架中的一个非常重要的接口,它定义了一些回调方法,用于让Spring容器感知到特定的组件或资源。通过实现Aware接口,我们可以让Spring容器向特定的组件注入自己所持有的一些资源,或者让Spring容器调用特定的组件方法来对其进行初始化或其他操作。这样,我们就可以更方便地管理组件和资源,将它们更好地整合到Spring应用程序中。

二、开始学习

1、新建项目,结构如下

 2、添加 spring 依赖
 <!-- spring 的核心依赖 --><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency></dependencies>
 3、在 service 包下新建一个 UserService 类

@Slf4j
@Service
public class UserService implements BeanNameAware {/*** 注入 bean 的名字*/private String beanName;/*** 容器会通过这个 set 方法将 bean 的名称注入进来** @param beanName*/@Overridepublic void setBeanName(String beanName) {this.beanName = beanName;}public void add() {log.info("添加用户,使用 beanName:" + this.beanName);}}

BeanNameAware是一个Spring框架提供的接口,实现该接口可以让类获取到自己在容器中的名称。在这个示例中,UserService实现了BeanNameAware接口,通过重写其中的setBeanName()方法,获取了自身在容器中的名称,并保存在了beanName字段中。

这个字段虽然看似没有实际作用,但在某些场景下是比较有用的。例如,在项目中可能存在多个名字不同但功能相同的类,使用beanName字段就可以区分它们。又或者,在将来需要对某种类型的Bean进行特殊的处理时,也可以根据beanName来进行判断和操作。

同时,@Slf4j注解是Lombok库提供的注解,可以自动生成log对象,使用log.info()等方法输出日志信息。在这个示例中,UserService类中的add()方法使用了log.info()输出了一条包含beanName字段的日志信息。

综合起来看,这段代码中的BeanNameAware@Slf4j注解,虽然看似没有实际作用,但还是提供了一些便利和可扩展性。

Aware 接口(感知型接口),当 spring 容器发现某个 bean,实现了 Aware 接口以后,name 就会为这个 bean 注入一些容器核心对象,比如某些业务场景中需要得到 bean 的名字或者 id 时,可以通过此接口来获取。

4、 在 config 包下新建一个 AppConfig 类和 ApplicationContextHolder 工具类

AppConfig 类

@Configuration
@ComponentScan(basePackages = "edu.nf.ch22")
public class AppConfig {
}

AppConfig是一个配置类,使用了@Configuration注解来标识它是一个配置类。配置类主要用于定义和配置应用程序中的Bean,通常与Spring的IoC容器一起使用。

@ComponentScan注解是用来指定扫描组件的基础包路径的。在这个示例中,basePackages属性指定了需要扫描的基础包路径为edu.nf.ch22。这意味着Spring容器会扫描该路径下的所有类,并将符合条件的类注册为Bean。

通过@ComponentScan注解,Spring会自动扫描并创建被@Component@Service@Repository@Controller等注解修饰的类的实例,并将其纳入IoC容器进行管理。

ApplicationContextHolder 工具类

public class ApplicationContextHolder implements ApplicationContextAware {/*** 声明容器*/private static ApplicationContext applicationContext;/*** 通过 set 方法将容器本身给注入进来** @param appContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext appContext) throws BeansException {applicationContext = appContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}/*** 封装了容器的 getBean 方法* @param id* @param clazz* @param <T>* @return*/public static <T> T getBean(String id, Class<T> clazz) {return applicationContext.getBean(id, clazz);}/*** 封装容器 getBean 方法* @param clazz* @param <T>* @return*/public static <T> T getBean(Class<T> clazz){return applicationContext.getBean(clazz);}}

 ApplicationContextHolder是一个实现了ApplicationContextAware接口的类,用于获取和管理Spring的应用上下文。

首先,该类声明了一个静态的applicationContext字段,用于保存应用上下文对象。

然后,通过实现setApplicationContext()方法,将应用上下文对象注入到applicationContext字段中。当Spring容器初始化时,会自动调用setApplicationContext()方法,并传入应用上下文对象。

接下来,该类提供了两个静态方法:

  1. getApplicationContext():用于获取应用上下文对象,即返回保存在applicationContext字段中的对象。

  2. getBean():封装了应用上下文的getBean()方法,提供了两个重载版本。一个是根据id和Class类型获取Bean对象,另一个是根据Class类型获取Bean对象。这两个方法可以方便地在应用中获取被Spring管理的Bean对象。

通过使用ApplicationContextHolder类,我们可以在任何地方获取到Spring的应用上下文对象,并使用其提供的方法获取需要的Bean对象,避免了在代码中手动获取或保持应用上下文对象的麻烦。这样可以更方便地管理和使用Spring容器中的组件。

 5、在 service 包下再建一个 StuService  类

@Service
@Slf4j
public class StuService  {public void add(){// 直接使用 ApplicationContextHolderUserService bean = ApplicationContextHolder.getBean("userService",UserService.class);bean.add();}}

StuService类中,使用了ApplicationContextHolder来获取UserService的实例并调用其方法。

首先,StuService类被标记为@Service注解,表示它是一个服务组件,会被Spring容器扫描并管理。

add()方法中,通过ApplicationContextHolder.getBean()方法从应用上下文中获取名为"userService"的UserService实例,并将其赋值给bean变量。

然后,调用bean.add()方法,即调用UserService实例的add()方法。

通过使用ApplicationContextHolder.getBean()方法,我们可以在StuService中直接获取其他被Spring管理的Bean,而不需要依赖注入或手动创建对象。这样可以方便地在不同的组件之间进行交互和调用,提高代码的可维护性和灵活性。

 6、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService bean = context.getBean(UserService.class);bean.add();}}

运行结果

 Aware 接口(感知型接口),当 spring 容器发现某个 bean,实现了 Aware 接口以后,name 就会为这个 bean 注入一些容器核心对象,比如某些业务场景中需要得到 bean 的名字或者 id 时,可以通过此接口来获取。

三、使用 BeanNameAware、ApplicationContextAware 这两个接口的好处

BeanNameAware 接口和 ApplicationContextAware 接口是 Spring Framework 提供的 Aware 接口之一,它们分别用于在 Bean 实例化和初始化过程中获取相关的信息和资源。它们的使用可以带来以下好处:

  1. BeanNameAware 接口的好处:

    • 获取当前 Bean 在容器中的名称:通过实现 BeanNameAware 接口,可以在 Bean 初始化阶段获得当前 Bean 在容器中的名称,这样在后续的操作中可以根据名称进行进一步的处理或判断。
  2. ApplicationContextAware 接口的好处:

    • 访问容器对象:通过实现 ApplicationContextAware 接口,可以在 Bean 初始化阶段获取到 Spring 容器的上下文对象(ApplicationContext),从而可以直接使用容器提供的各种功能,如获取其他 Bean、发布事件等。
    • 获取环境信息:ApplicationContext 接口继承了 EnvironmentCapable 接口,因此可以通过实现 ApplicationContextAware 接口来获取当前环境的相关信息,包括配置文件中的属性值、系统变量等。这样可以根据环境信息作出不同的处理逻辑。

综上所述,BeanNameAware 和 ApplicationContextAware 接口的使用可以让你的 Bean 在实例化和初始化过程中获得更多的信息和资源,使其能够更好地适应和利用 Spring 容器的功能。通过这些接口,你可以在 Bean 中获取到容器中的其他 Bean、环境信息等,并根据这些信息进行相应的处理和操作,增加了代码的灵活性和可扩展性。然而,在使用这些 Aware 接口时,需要注意避免过度依赖容器的实现细节,保持代码的松耦合性,以便提高代码的可测试性和可维护性。

四、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OJ第四篇

文章目录 链表分割环形链表有效的括号 链表分割 链接: 链表分割 虽然这个题牛客网中只有C,但是无所谓&#xff0c;我们只要知道C是兼容C的就可以了 至于说这个题的思路&#xff0c;我们就弄两个链表&#xff0c;把小于x的结点放到一个链表中&#xff0c;剩下的放到另一个链表…

从实时数据库转战时序数据库,他陪伴 TDengine 从 1.0 走到 3.0

关于采访嘉宾 在关胜亮的学生时代&#xff0c;“神童”这个称号如影随形&#xff0c;很多人初听时会觉得这个称谓略显夸张&#xff0c;有些人还会认为这是不是就是一种调侃&#xff0c;但是如果你听说过他的经历&#xff0c;就会理解这一称号的意义所在了。 受到教师母亲的影…

SpringCloud学习笔记-gateway网关自定义全局过滤器

需求&#xff1a;定义全局过滤器&#xff0c;拦截请求&#xff0c;判断请求的参数是否满足下面条件&#xff1a; 参数中是否有authorization&#xff0c; authorization参数值是否为admin 如果同时满足则放行&#xff0c;否则拦截 实现&#xff1a; 在gateway中定义一个过…

ScaleButton缩放按钮的实现基于javascript,typescript的代码-复制即用

调用方法 newChestInstance(sp:cc.SpriteFrame,pos:cc.Vec3){var node = new cc.Node("New Sprite");var sprite = node.addComponent(cc.Sprite);node.parent = this.canvasRoot;sprite.spriteFrame = sp;sprite.node.position = pos;node.addComponent(ChestView);…

创建React Native的第一个hello world工程

创建React Native的第一个hello world工程 需要安装好node、npm环境 如果之前没有安装过react-native-cli脚手架的&#xff0c;可以按照下述步骤直接安装。如果已经安装过的&#xff0c;但是在使用这个脚手架初始化工程的时候遇到下述报错的话 cli.init(root, projectname);…

CEC2013(MATLAB):狐猴优化算法(Lemurs Optimizer,LO)求解CEC2013(提供MATLAB代码及参考文献)

一、狐猴优化算法 狐猴优化算法&#xff08;Lemurs Optimizer&#xff0c;LO&#xff09;由Ammar Kamal Abasi等人于2022年提出&#xff0c;该算法模拟狐猴的跳跃和跳舞行为&#xff0c;具有结构简单&#xff0c;思路新颖&#xff0c;搜索速度快等优势。狐猴优化算法&#xff…

GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术深度应用

以地下水数值模拟软件GMS操作为主要授课内容&#xff0c;在教学中强调模块化教学&#xff0c;分为前期数据收集与处理&#xff1b;三维地质结构建模&#xff1b;地下水流动模型构建&#xff1b;地下水溶质运移模型构建和反应性溶质运移构建5个模块&#xff1b;采用全流程模式将…

简单易学,让你拥有个性化的二维码

在数字化时代&#xff0c;二维码已经成为了我们日常生活的一部分。然而&#xff0c;大多数二维码都是简单而乏味的&#xff0c;缺乏个性和吸引力。这篇文章将向你介绍如何使用乔拓云等免费在线海报制作工具来制作艺术二维码&#xff0c;让你轻松掌握二维码的美化技巧。 1. 选择…

threejs(2)-Geometry进阶详解

一、全面讲解UV与应用 在本节中&#xff0c;我们将讨论Three.js中的UV映射&#xff0c;包括UV映射的概念、与顶点位置的关系和区别以及如何在Geometry中设置UV坐标。我们将使用BufferGeometry进行示例说明。 颜色对应 什么是UV映射&#xff1f; UV映射是一种将二维纹理映…

HTML代码中引入CSS样式的三种方式

1.内联样式: 使用style属性将CSS样式直接嵌入到HTML元素中.例如 2.内部样式表 3.引入外部样式

“岗课赛证”融通的物联网综合实训室建设方案

一、概述 随着5G技术的普及应用和产业经济的革新发展,物联网产业所呈现的广阔前景带来了对创新型技术技能人才的迫切需求。高职院校物联网专业建设也因此转变为面向国家战略性新兴产业发展需求。当前,“岗位课程竞赛证书”融通的培育理念,是高职院校物联网人才培养和专业优化的…

计网 七层网络模型

计网 七层网络模型 一.协议&#xff08;protocol&#xff09; 1.什么是协议 数据在网络中传输时按照的规则就是协议&#xff08;protocol&#xff09; 协议&#xff08;protocol&#xff09;规定了数据在网络中传输的顺序&#xff0c;格式&#xff0c;以及携带哪些内容 二…