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.mzph.cn/news/110203.shtml

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

相关文章

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…

Elasticsearch系列组件:Beats高效的日志收集和传输解决方案

Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎&#xff0c;设计用于云计算环境中&#xff0c;能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性&#xff0c;可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个…

接口自动化测试持续集成,Soapui接口功能测试参数化

按照自动化测试分层实现的原理&#xff0c;每一层的脚本实现都要进行参数化&#xff0c;自动化的目标就是要实现脚本代码与测试数据分离。当测试数据进行调整的时候不会对脚本的实现带来震荡&#xff0c;从而提高脚本的稳定性与灵活度&#xff0c;降低脚本的维护成本。Soapui最…

C#,数值计算——KMeans分类的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// K-Means classification /// </summary> public class Kmeans { private int nn { get; set; } private int mm { get; set; } private …

优维低代码实践:片段

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

5.12.webrtc接口调用过程

嗨&#xff0c;大家好&#xff0c;我是李超&#xff0c;在上节课中呢&#xff0c;我向你介绍了外接口的设计以及我们红接口展开之后的样子&#xff0c;对吧&#xff1f;那今天呢&#xff1f;我们再来看看整个接口调用过程。那整个这个调用过程啊&#xff0c;非常的复杂&#xf…

QCustomPlot实现曲线拖拽

本文内容目录 需求场景&#xff1a;一、选择控件二、将QCustomPlot库整合到你的Qt项目中1、下载源代码2、创建.pri 三、鼠标框选&#xff0c;实现坐标缩放四、曲线拖动1、定位曲线2、移动时改变曲线 五、问题的产生与解决1、查看源码2、修改本项目代码 需求场景&#xff1a; 曲…

excel 日期与时间戳的相互转换

1、日期转时间戳&#xff1a;B1INT((A1-70*365-19)*86400-8*3600)*1000 2、时间戳转日期&#xff1a;A1TEXT((B1/10008*3600)/8640070*36519,"yyyy-mm-dd hh:mm:ss") 以上为精确到毫秒&#xff0c;只精确到秒不需要乘或除1000。 使用以上方法可以进行excel中日期…

行业追踪,2023-10-18

自动复盘 2023-10-18 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

Redis LFU缓存淘汰算法

前言 Redis 在 4.0 版本之前的缓存淘汰算法&#xff0c;只支持 random 和 lru。random 太简单粗暴了&#xff0c;可能把热点数据给淘汰掉&#xff0c;一般不会使用。lru 比 random 好一点&#xff0c;会优先淘汰最久没被访问的数据&#xff0c;但是它也有一个缺点&#xff0c;…

英语——分享篇——每日200词——1001-1200

1001——responsibility——[rɪˌspɒnsəbɪlətɪ]——n.责任——responsibility——res热死(拼音)ponsi胖子(谐音)bili比利(拼音)ty题(谐音)——热死的胖子比利做题时很有责任心——The responsibility for her family bears down on a young woman.——家庭的责任沉重地落…

攻防世界web篇-PHP2

直接点击进入到http网页中&#xff0c;会得到这样一个界面 这里&#xff0c;我最开始使用了burp什么包也没有抓到&#xff0c;然后接着又用nikto进行探测&#xff0c;得到的只有两个目录&#xff0c;当时两个目录打开后&#xff0c;一个是fond界面&#xff0c;一个是这个网页的…

【QT】常用控件——按钮组

继承Widget PushButton 设置图片&#xff0c;先导入图片资源&#xff0c;见&#xff1a;【QT】资源文件导入_复制其他项目中的文件到qt项目中_StudyWinter的博客-CSDN博客 在布局中添加图片 调整尺寸 toolButton 显示图片、文本 显示图片&#xff08;图片和文字都有时&#…

使用Python+selenium实现第一个自动化测试脚本

这篇文章主要介绍了使用Pythonselenium实现第一个自动化测试脚本&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 最近在学web自动化&#xff0c;记录一下学习过程。…

快速解决 Resource not accessible by integration

简介 最近好久没有写博客了&#xff0c;今天在写开源项目 python-package-template 的时候&#xff0c;正好遇到一个问题&#xff0c;记录一下吧。本文将介绍 Resource not accessible by integration 的几种解决方案。 也欢迎大家体验一下 python-package-template 这个项目&…

黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220)rust解法

你的任务是模拟黑白棋游戏的进程。黑白棋的规则为&#xff1a;黑白双方轮流放棋子&#xff0c;每次必须让新放的棋子“夹住”至少一枚对方棋子&#xff0c;然后把所有被新放棋子“夹住”的对方棋子替换成己方棋子。一段连续&#xff08;横、竖或者斜向&#xff09;的同色棋子被…

SpringCloud: sentinel热点参数限制

一、定义controller package cn.edu.tju.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.web.bind.annotation.PathVariable; import org.springframewo…

Unity笔记--渲染顺序

目录 Unity中的渲染顺序一、Camera层二、透明类型&#xff08;先渲染不透明&#xff09;三、物体的SortingLayer&#xff08;越小越先渲染&#xff09;四、sorting order&#xff08;越小越先渲染&#xff09;五、RenderQueue &#xff08;越小越优先&#xff09;六、距离相机z…

【算法设计zxd】第6章 回溯法

目录 6.1 回溯法的设计技术 &#xff1a; 四皇后问题 回溯法&#xff1a; 算法框架&#xff1a; 思考题&#xff1a; 回溯算法的适用条件 【例6-1】求满足下列不等式的所有整数解&#xff1a; 6.2回溯算法的经典例题 【例6-2】装载问题  问题分析 计算模型  算法设计与描…

BookStack 详解及 Docker-Compose 部署

BookStack 是一款用于创建文档和文档管理的开源平台。它提供了一个直观且功能丰富的界面&#xff0c;可用于组织和管理各种文档&#xff0c;包括文档编写、编辑和共享。本文将介绍 BookStack 的核心功能&#xff0c;并展示如何使用 Docker-Compose 快速部署 BookStack。 BookS…