第一讲:BeanFactory和ApplicationContext接口

news2024/11/24 14:21:35

BeanFactory和ApplicationContext接口

  • 1. 什么是BeanFactory?
  • 2. BeanFactory能做什么?
  • 3.ApplicationContext对比BeanFactory的额外功能?
    • 3.1 MessageSource
    • 3.2 ResourcePatternResolver
    • 3.3 EnvironmentCapable
    • 3.4 ApplicationEventPublisher
  • 4.总结


1. 什么是BeanFactory?

BeanFactory是ApplicationContext的父接口,是真正的Spring核心容器,主要的ApplicationContext实现都【组合】了他的功能。


2. BeanFactory能做什么?

首先先看一下BeanFactory的接口定义:
在这里插入图片描述

表面上只有getBean功能,实际上控制反转、基本的依赖注入、直至Bean的生命周期的各种功能,都由他的实现类提供,例如:DefaultListableBeanFactory

DefaultListableBeanFactory不仅仅实现了BeanFactory,还额外拓展了非常多的接口,例如:SingletonBeanRegistry(单例),其实现类中的私有成员变量DefaultSingletonBeanRegistry#singletonObjects,包含了所有的单例Bean对象。

接下来,我们可以试着获取到容器中所有的单例对象(因为是私有成员变量,所以需要通过反射来暴力破解)。核心代码如下:

Field field = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
field.setAccessible(true);
// 获取到BeanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map<String, Object> singletons = (Map<String, Object>)field.get(beanFactory);

在这里插入图片描述


3.ApplicationContext对比BeanFactory的额外功能?

在这里插入图片描述

从上图可以看出,ApplicationContext对比BeanFactory额外拓展了一些功能,主要是EnvironmentCapableMessageSourceApplicationEventPublisherResourcePatternResolver

下面,我们逐个分析这几个功能。

  • MessageSource:支持项目的国际化
  • ResourcePatternResolver:通过通配符来获取文件
  • EnvironmentCapable:获取系统变量或者应用中定义的变量
  • ApplicationEventPublisher:发布事件

3.1 MessageSource

在项目的资源目录下,创建一个Resouce Bundle
在这里插入图片描述

共包含3个文件,所有语言通用的messages.properties、中文、英文。

// 测试MessageSource接口的功能
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));

在这里插入图片描述

控制台分别输出了你好hello, Locale一般是浏览器发起请求时,会自动携带的,因此不需要在代码里面写死。

3.2 ResourcePatternResolver

ResourcePatternResolver可以通过通配符来获取文件,如下:

  • classpath: : 从第一个classpath中加载。
  • classpath*: : 从所有的classpath中加载。
  • file: : 从文件系统加载资源。
  • jar: : 用于从 jar 文件加载的 URL 前缀。
  • war: : 用于从 Tomcat 上的war文件加载的 URL 前缀。
// 测试ResourcePatternResolver的功能
Resource[] resources = context.getResources("classpath*:/META-INF/spring.factories");
Lists.newArrayList(resources).forEach(System.out::println);

可以发现,所有的spring.factories文件都被找到了。

在这里插入图片描述

3.3 EnvironmentCapable

可以获取到服务器上的变量或者应用中的变量。变量名称不区分大小写

// 测试EnvironmentCapable的功能
ConfigurableEnvironment environment = context.getEnvironment();
System.out.println("JAVA_HOME:" + environment.getProperty("java_home"));
System.out.println("Server port is: " + environment.getProperty("server.port"));

在我的电脑中配置的JAVA_HOME是大写的,这边写小写,依然可以读取到。

在这里插入图片描述

3.4 ApplicationEventPublisher

事件发布器是Spring中非常重要的一个机制,属于发布订阅模式。可以用来解耦业务,支持异步执行。


public class UserRegisteredEvent extends ApplicationEvent {

    /**
     * 用户手机号码
     */
    private String phone;

    public UserRegisteredEvent(Object source, String phone) {
        super(source);
        this.phone = phone;
    }
}

首先编写一个用户注册事件类,继承于ApplicationEvent, 有一个自定义的成员变量:phone

/**
 * 完成用户注册逻辑
 *
 * @Date 2023/8/20 11:30
 */
@Component
@Slf4j
public class Component01 {

    @Resource
    private ApplicationEventPublisher eventPublisher;

    public void handleUserRegistered() {
        log.info("用户注册~");
        // 发布用户已注册事件
        eventPublisher.publishEvent(new UserRegisteredEvent(this, "119"));
    }
}

Component01处理用户注册逻辑,并且发布了上述事件。

/**
 * 事件监听器
 *
 * @Date 2023/8/20 11:30
 */
@Component
@Slf4j
public class Component02 {

    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        log.info("发送短信了~");
    }
}

Component02由于handleUserRegistered方法上标注了@EventListener注解,并且方法的参数为UserRegisteredEvent,说明这个组件监听了该事件。就可以做后续的业务处理了。

// 测试ApplicationEventPublisher的功能
Component01 bean = (Component01) context.getBean("component01");
bean.handleUserRegistered();

最后,在main方法中模拟调用一下,结果如下:

在这里插入图片描述


4.总结

BeanFactory和ApplicationContext并不仅仅是简单的接口继承关系,ApplicationContext组合并扩展了BeanFactory的功能。

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

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

相关文章

docker的资源控制及数据管理

docker的资源控制及docker数据管理 一.docker的资源控制 1.CPU 资源控制 1.1 资源控制工具 cgroups&#xff0c;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被 namespace 隔离起来的资源&#xff0c; 还可以为资源设置权重、计算使用量、操控进程启停等等。 …

面试汇总-testcase

朋友圈点赞的测试用例 功能测试 1点赞后是否显示结果 2.点赞后是否可以取消; 3.点赞取消后是否可以重复点赞; 4.共同好友点赞后&#xff0c;是否有消息提醒; 5.非共同好友点赞后&#xff0c;是否有消息提醒; 6.点击点赞人昵称&#xff0c;是否可以跳转到他/她的主页; 7.自己能…

对象头的结构

一、对象头的结构(32位虚拟机) 1、普通对象 普通对象头占用64 bits &#xff0c;其中Mark word占32 bits &#xff0c;Klass Words 占32bits。Klass Words 可以理解为指针&#xff0c;指向类对象。Mark Word下面会详解。 2、数组对象 数组对象增加了4个字节的空间&#xff0c;…

百度许少辉著Baidu《乡村振兴战略下传统村落文化旅游设计》图书馆新书通报

百度许少辉著Baidu《乡村振兴战略下传统村落文化旅游设计》图书馆新书通报

【C语言学习】二维数组

二维数组 int[3][5];//通常理解为a是一个3行5列的矩阵二维数组的遍历 for(i0; i<3; i){for(j0; j<5; j){a[i][j] i*j;} }

删除链表中的节点(力扣)

目录 题目&#xff1a; 看着花里胡哨&#xff0c;小卡拉米四行代码秒杀&#xff01; 示例&#xff1a; 思路&#xff1a; 代码&#xff1a; 题目&#xff1a; 看着花里胡哨&#xff0c;小卡拉米四行代码秒杀&#xff01; 示例&#xff1a; 思路&#xff1a; 把后一个节点的…

多线程实现与管理

进程与线程 进程 &#xff1a; 进程是操作系统进行资源分配的最小单位&#xff0c;每执行一个程序、一条命令操作系统都会启动一个进程&#xff0c;进程是一个程序的执行过程&#xff0c;当程序启动时&#xff0c;操作系统会把进程的代码加载到内存中&#xff0c;并为新进程分配…

Python爬虫——scrapy_日志信息以及日志级别

日志级别&#xff08;由高到低&#xff09; CRITICAL&#xff1a; 严重错误 ERROR&#xff1a; 一般错误 WARNING&#xff1a; 警告 INFO&#xff1a; 一般警告 DEBUG&#xff1a; 调试信息 默认的日志等级是DEBUG 只要出现了DEBUG或者DEBUG以上等级的日志&#xff0c;那么这些…

开集输出和开漏输出

​​​​​​ 首先指明一下以下8中GPIO输入输出模式&#xff1a; GPIO_Mode_AIN 模拟输入&#xff1b; GPIO_Mode_IN_FLOATING 浮空输入&#xff1b; GPIO_Mode_IPD 下拉输入&#xff1b; GPIO_Mode…

JVM面试题-2

1、有哪几种垃圾回收器&#xff0c;各自的优缺点是什么&#xff1f; 垃圾回收器主要分为以下几种&#xff1a;Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1&#xff1b; Serial:单线程的收集器&#xff0c;收集垃圾时&#xff0c;必须stop the worl…

RPM包的概念以及制作过程

RPM包的概念以及制作过程 1. 软件包管理工具的背景介绍2. RPM&#xff08;Red-Hat Package Manager&#xff09;2.1 rpm包的命名规范2.2 rpm的基础命令2.3 安装与卸载 3. RPM包的制作3.1 源码包的制作3.2 .spec配置文件的构建3.3 rpmbuild命令编译验证 4. 软件仓库制作4.1 安装…

QChart:数据可视化(用图像形式显示数据内容)

1、数据可视化的图形有&#xff1a;柱状/线状/条形/面积/饼/点图、仪表盘、走势图&#xff0c;弦图、金字塔、预测曲线图、关系图、数学公式图、行政地图、GIS地图等。 2、在QT Creator的主页面&#xff0c;点击 欢迎》示例》右侧输入框 输入Chart&#xff0c;即可查看到QChar…

鲁棒优化入门(5)—Matlab+Yalmip求解鲁棒优化编程实战

之前的博客&#xff1a;鲁棒优化入门&#xff08;二&#xff09;——基于matlabyalmip求解鲁棒优化问题 去年发布了使用Yalmip工具箱求解鲁棒优化问题的博客之后&#xff0c;陆陆续续有朋友问我相关的问题&#xff0c;有人形容从学习这篇博客到求解论文中的鲁棒优化问题&#x…

redis--主从复制

redis主从复制 Redis 主从复制是一种用于实现数据复制和数据备份的机制&#xff0c;它允许将一个 Redis 服务器的数据复制到其他 Redis 服务器上。主从复制在 Redis 中通常用于构建高可用性架构、读写分离以及数据分析等场景。 主从复制的角色 主服务器&#xff08;Master&a…

互斥锁、自旋锁、读写锁和文件锁

互斥锁 互斥锁&#xff08;mutex&#xff09;又叫互斥量&#xff0c;从本质上说是一把锁&#xff0c;在访问共享资源之前对互斥锁进行上锁&#xff0c;在访问完成后释放互斥锁&#xff08;解锁&#xff09;&#xff1b;对互斥锁进行上锁之后&#xff0c;任何其它试图再次对互斥…

python中文热词统计demo

背景 老人家不识字&#xff0c;在城市生活不便&#xff0c;喜欢去基督教堂&#xff0c;但是听不懂&#xff0c;也难以和姊妹们(老头老太太们)交流。于是想教他识字&#xff0c;从哪里教起呢&#xff0c;不如从 《圣经》的常用字词开始吧&#xff0c;于是花了几分钟把《圣经》热…

LeetCode 周赛上分之旅 #40 结合特征压缩的数位 DP 问题

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

构建 NodeJS 影院微服务并使用 docker 部署它(02/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 图片取自网络 — 封面由我制作 这是✌️“构建 NodeJS 影院微服务”系列的第二篇文章。 二、对第一部分的…

8.3.tensorRT高级(3)封装系列-tensor封装,索引计算,内存标记及自动复制

目录 前言1. Tensor封装总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-tensor封装&#xff0c;索引计算&a…

cuOSD(CUDA On-Screen Display Library)库的学习

目录 前言1. cuOSD1.1 Description1.2 Getting started1.3 For Python Interface1.4 Demo1.5 Performance Table 2. cuOSD案例2.1 环境配置2.2 simple案例2.3 segment案例2.4 segment2案例2.5 polyline案例2.6 comp案例2.7 perf案例 3. cuOSD浅析3.1 simple_draw函数 4. 补充知…