Spring framework Day22:Aware接口

news2024/11/15 12:23:28

前言

在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
     */
    @Override
    public 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
     */
    @Override
    public 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(){
        // 直接使用 ApplicationContextHolder
        UserService 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.coloradmin.cn/o/1107098.html

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

相关文章

媒体转码和输出软件:Media Encoder 2024中文版

想要高效地转码、优化输出吗&#xff1f;那就来尝试全新的Media Encoder 2024吧&#xff01;Media Encoder是Adobe公司出品的一款媒体转码和输出软件&#xff0c;可以帮助您快速、高效地将多种格式的视频和音频转换为所需的输出格式。 全新的Media Encoder 2024提供了更加智能…

【CANoe】XML Test Module使用实例

文章目录 一、实操步骤1、增加XML Test Module节点2、配置XML Test Module节点3、XML Test Module节点增加CAPL脚本(.can文件)4、文件夹结构5、使用仿真节点开始测试6、测试结果与测试报告7、同理&#xff0c;在Test Setup也可如此操作 一、实操步骤 1、增加XML Test Module节…

使用conda install一直卡在solving environment的解决方法

使用国内镜像源&#xff0c;但install仍旧一直卡在solving environment&#xff0c;超过10分钟就不用等了&#xff1b; 检查C:\Users\UserName 路径下的.condarc文件 将这个defaults这一行删掉即可

【Linux-常用命令-基础命令-复制-copy-命令-笔记】

【Linux-常用命令-基础命令-复制文件-copy-命令-笔记】 1、前言2、操作3、自己的实践 1、前言 最近&#xff0c;在使用Linux的时&#xff0c;使用相关基础命令是&#xff0c;总是容易忘记&#xff0c;上网一搜&#xff0c;大部分都写的比较繁琐&#xff0c;我就找下复制命令&a…

【算法设计与分析qwl】04 NP-hard——只是举例几个,货郎,双机调度,01背包

NP-hard问题&#xff1a; 有效算法是 输入规模的多项式时间算法。 这些问题的难度处于可有效计算的边界。 算法数据结构程序设计 例4 货郎问题 建模与算法&#xff1a; 解是一个排列&#xff0c; 0-1背包问题&#xff1a; 建模&#xff1a; 双机调度&#xff1a; 建模&#x…

【PPT技巧】如何将多张幻灯片打印在一张纸上?

PPT页面很多&#xff0c;想在打印的时候&#xff0c;多张幻灯片放置在同一页面&#xff0c;也就是打印在一张纸上&#xff0c;如何设置呢&#xff1f; 首先&#xff0c;打开需要打印的PPT文件&#xff0c;点击菜单选项卡【文件】&#xff0c;然后在弹出的页面中点击【打印】选…

单链表经典OJ题:找出链表的中间节点

题目&#xff1a; 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点。 图例&#xff1a; 解法&#xff1a; 解法1: 先遍历链表确定链表节点的数量&#xff0c;然后再找到中间位置的节点 解法2: 快慢…

Linux性能优化--补充

14.1. 性能工具的位置 本书描述的性能工具来源于Internet上许多不同的位置。幸运的是&#xff0c;大多数主要发行版都把它们放在一起&#xff0c;包含在了其发行版的当前版本中。表A-1描述了全部工具&#xff0c;提供了指向其原始源位置的地址&#xff0c;并注明它们是否包含在…

百度地图高级进阶开发:圆形区域周边搜索地图监听事件(覆盖物重叠显示层级\图像标注监听事件、setZIndex和setTop方法)

百度地图API 使用百度地图API添加多覆盖物渲染时&#xff0c;会出现覆盖物被相互覆盖而导致都无法触发它们自己的监听&#xff1b;在百度地图API里&#xff0c;map的z-index为0&#xff0c;但是触发任意覆盖物的监听如click时也必定会触发map的监听&#xff1b; 项目需求 在…

6.7 案例分析与实现

思维导图&#xff1a; 6.7 案例分析与实现 #### 案例6.2: 六度空间理论 【案例分析】 - **背景介绍**&#xff1a; 六度空间理论提及在任意两人之间最多仅有6个人的连接。尽管这一理论被广泛提及并得到了某种程度的验证&#xff0c;但从科学角度看&#xff0c;它仍然只是一…

模型的选择与调优(网格搜索与交叉验证)

1、为什么需要交叉验证 交叉验证目的&#xff1a;为了让被评估的模型更加准确可信 2、什么是交叉验证(cross validation) 交叉验证&#xff1a;将拿到的训练数据&#xff0c;分为训练和验证集。以下图为例&#xff1a;将数据分成4份&#xff0c;其中一份作为验证集。然后经过…

C/C++面试常见问题——指针和引用的区别

首先想要理解指针和引用的区别&#xff0c;我们要明确什么是指针&#xff0c;什么是引用 一&#xff0c;指针和引用的基本概念及特性 指针是一个特殊变量&#xff0c;其中存储着所指向变量的地址 指针主要有以下特性&#xff1a; 1. 在使用时需要*解引用 2. sizeof(指针)的…

关于我对 jeecg-boot 的项目理解、使用心得和改进建议

一句话总结&#xff1a; JeecgBoot帮助我提升了后端技术水平&#xff0c;入门了前端&#xff0c;让我在公司内部慢慢能够成长为全栈开发。 一、项目理解 JeecgBoot 项目的核心理念是快速开发、低代码、易扩展。它采用了前后端分离的架构&#xff0c;后端使用Spring Boot Myba…

5.覆盖增强技术——PUCCHPUSCH

PUSCH增强方案的标准化工作 1.PUSCH重复传输类型A增强&#xff0c;包括两种增强机制&#xff1a;增加最大重复传输次数&#xff0c;以及基于可用上行时隙的重复传输次数技术方式。 2.基于频域的解决方案&#xff0c;包括时隙间/时隙内跳频的增强 3.支持跨多个时隙的传输块&…

spring配置文件第一行导致读取配置失败

遇到读取配置存在问题&#xff0c;尤其当配置到第一行 通过spring执行测试类&#xff0c;没有问题&#xff0c;但是相同配置启动项目时&#xff0c;老找不到JdbcTemplate 使用配置&#xff1a; spring.shardingsphere.datasource.namesmaster,slavespring.shardingsphere.dat…

服务器往浏览器推消息(SSE)应用

1&#xff0c;SSE 和 WebSocket 对比 SSE&#xff08;服务器发送事件&#xff09; SSE是一种基于HTTP的单向通信机制&#xff0c;用于服务器向客户端推送数据。它的工作原理如下&#xff1a; 建立连接&#xff1a;客户端通过发送HTTP请求与服务器建立连接。在请求中&#xff…

【linux API 分析】register_chrdev

linux kernel&#xff1a;4.19 在注册字符设备的时候&#xff0c;可使用register_chrdev()函数&#xff0c;其对应的注销函数是unregister_chrdev()&#xff0c;其定义是在include\linux\fs.h文件 register_chrdev() 首先分析register_chrdev()函数 其定义如下 static inlin…

SMAP(Soil Moisture Active and Passive)数据下载

SMAP&#xff08;Soil Moisture Active and Passive&#xff09;数据下载 打开网站先注册登录用户 然后打开SMAP下载的网站 点击HTTPS File System进入下载页面 然后点击HDF文件下载 下载之后在HDF View里面预览

Spring中反转控制与依赖注入

目录 一、反转控制&#xff08;IOC&#xff09; 二、依赖注入&#xff08;DI&#xff09; 一、反转控制&#xff08;IOC&#xff09; 在以前的学习中为成员变量的赋值&#xff0c;一般都是直接在代码中完成&#xff0c;但是这种方式会产生耦合。然而利用Spring对成员变量赋值可…

QT学习day2

一、思维导图 作业&#xff1a; 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admi…