第一讲:BeanFactory和ApplicationContext接口

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 {@Resourceprivate 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 {@EventListenerpublic 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.mzph.cn/news/45462.shtml

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

相关文章

解决C#报“MSB3088 未能读取状态文件*.csprojAssemblyReference.cache“问题

今天在使用vscode软件C#插件&#xff0c;编译.cs文件时&#xff0c;发现如下warning: 图(1) C#报cache没有更新 出现该warning的原因&#xff1a;当前.cs文件修改了&#xff0c;但是其缓存文件*.csprojAssemblyReference.cache没有更新&#xff0c;需要重新清理一下工程&#x…

【机器学习实战】朴素贝叶斯:过滤垃圾邮件

【机器学习实战】朴素贝叶斯&#xff1a;过滤垃圾邮件 0.收集数据 这里采用的数据集是《机器学习实战》提供的邮件文件&#xff0c;该文件有ham 和 spam 两个文件夹&#xff0c;每个文件夹中各有25条邮件&#xff0c;分别代表着 正常邮件 和 垃圾邮件。 这里需要注意的是需要…

【校招VIP】java语言考点之List和扩容

考点介绍&#xff1a; List是最基础的考点&#xff0c;但是很多同学拿不到满分。本专题从两种实现子类的比较&#xff0c;到比较复杂的数组扩容进行分析。 『java语言考点之List和扩容』相关题目及解析内容可点击文章末尾链接查看&#xff01;一、考点题目 1、以下关于集合类…

vue技术学习

vue快速入门 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>vue快速入门</title> </head> <body> <!--老师解读 1. div元素不是必须的&#xff0c;也可以是其它元素&#xff0…

操作系统——操作系统内存管理基础

文章目录 1.内存管理介绍2.常见的几种内存管理机制3.快表和多级页表快表多级页表总结 4.分页机制和分段机制的共同点和区别5.逻辑(虚拟)地址和物理地址6.CPU 寻址了解吗?为什么需要虚拟地址空间? 1.内存管理介绍 操作系统的内存管理主要是做什么&#xff1f; 操作系统的内存…

Apache DolphinScheduler 支持使用 OceanBase 作为元数据库啦!

DolphinScheduler是一个开源的分布式任务调度系统&#xff0c;拥有分布式架构、多任务类型、可视化操作、分布式调度和高可用等特性&#xff0c;适用于大规模分布式任务调度的场景。目前DolphinScheduler支持的元数据库有Mysql、PostgreSQL、H2&#xff0c;如果在业务中需要更好…

要跟静音开关说再见了!iPhone15新变革,Action按钮引领方向

有很多传言称iPhone 15 Pro会有很多变化&#xff0c;但其中一个变化可能意味着iPhone体验从第一天起就有的一项功能的终结。我说的是静音开关&#xff0c;它可以让你轻松地打开或关闭iPhone的铃声。 根据越来越多的传言&#xff0c;iPhone 15 Pro和iPhone 15 Pro Max将拆除静音…

基于.Net Core开发的医疗信息LIS系统源码

SaaS模式.Net Core版云LIS系统源码 医疗信息LIS系统是专为医院检验科设计的一套实验室信息管理系统&#xff0c;能将实验仪器与计算机组成网络&#xff0c;使病人样品登录、实验数据存取、报告审核、打印分发&#xff0c;实验数据统计分析等繁杂的操作过程实现了智能化、自动化…

【Git】(四)子模块

1、增加子模块 进入准备添加子模块所在的目录&#xff0c;例如library。 git submodule add -b 1.0.0.0 gitgitee.com:sunriver2000/SubModule.git参数-b用于指定子模块分支。 2、更新子模块 git submodule update --progress --init --recursive --force --remote -- "…

初出茅庐的小李博客之STM32CubeMx配置定时器的编码器模式

STM32CubeMx配置定时器的编码器模式 上次文章写了编码器是如何工作的&#xff0c;今天就来用STM32F103C8T6的TIM3的通道1跟通道2编写一个编码器识别程序。 编程思路&#xff1a; A相:TIM3_CH1 B相:TIM3_CH2 SWITCH:PB5&#xff08;外部中断的方式&#xff09; 实现效果&a…

STM32 串口复习

按数据通信方式分类&#xff1a; 串行通信&#xff1a;数据逐位按顺序依次传输。传输速率较低&#xff0c;抗干扰能力较强&#xff0c;通信距离较长&#xff0c;I/O资源占用较少&#xff0c;成本较低。并行通信&#xff1a;数据各位通过多条线同时传输。 按数据传输方向分类&…

Django进阶:DRF(Django REST framework)

什么是DRF&#xff1f; DRF即Django REST framework的缩写&#xff0c;官网上说&#xff1a;Django REST framework是一个强大而灵活的工具包&#xff0c;用于构建Web API。 简单来说&#xff1a;通过DRF创建API后&#xff0c;就可以通过HTTP请求来获取、创建、更新或删除数据(…

linux vscode 下开发

linux vscode 下开发 javajdk插件查看调用层次 java jdk 各种JAVA JDK的镜像分发 编程宝库 - 技术改变世界 jdk 镜像 ubuntu22.04 安装 # Linux x64 64位 jdk-8u351-linux-x64.tar.gztar -zxf jdk-8u351-linux-x64.tar.gz mv jdk1.8.0_351 jdk8/ vim ~/.pr…

Java并发编程之线程池详解

目录 &#x1f433;今日良言:不悲伤 不彷徨 有风听风 有雨看雨 &#x1f407;一、简介 &#x1f407;二、相关代码 &#x1f43c;1.线程池代码 &#x1f43c;2.自定义实现线程池 &#x1f407;三、ThreadPoolExecutor类 &#x1f433;今日良言:不悲伤 不彷徨 有风听风 有…

【汇编语言】关于“段”的总结

文章目录 各种段三种段具体案例截图数据段、栈段、代码段同时使用不同段地址数据段、栈段、代码段同时使用一个段地址![在这里插入图片描述](https://img-blog.csdnimg.cn/45c299950ad949e3a90b7ed012b3a9ee.png) 各种段 1、基础 物理地址 段地址 x 16 偏移地址 2、做法 编…

【数据结构】双链表

链表&#xff08;二&#xff09; 文章目录 链表&#xff08;二&#xff09;00 引入01 类的搭建02 得到链表的长度03 打印链表04 查找是否包含关键字key是否在链表当中05 头插法06 尾插法07 任意位置插入08 删除关键字为key的节点09 删除所有值为key的节点10 清空11 LinkedList常…

leetcode 198. 打家劫舍

2023.8.19 打劫问题是经典的动态规划问题。先设一个dp数组&#xff0c;dp[i]的含义为&#xff1a;前 i 个房屋能盗取的最高金额。 每间房屋无非就是偷&#xff0c;或者不偷这两种情况&#xff0c;于是可以写出递推公式&#xff1a; …

LeetCode235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归方法二&#xff1a;迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…

依赖预构建与静态资源处理

依赖预构建 vite是一个基于浏览器原生ES-Module的前端构建工具。 当你首次启动vite的时候&#xff0c;vite会在本地加载你的站点之前预构建项目依赖。 原因&#xff1a; CommonJS和UMD兼容性&#xff1a;在开发阶段中&#xff0c;Vite的开发服务器将所有的代码视为原生ES模块。…

浅谈日常使用的 Docker 底层原理-三大底座

适合的读者&#xff0c;对Docker有过简单了解的朋友&#xff0c;想要进一步了解Docker容器的朋友。 前言 回想我这两年&#xff0c;一直都是在使用 Docker&#xff0c;看过的视频、拜读过的博客&#xff0c;大都是在介绍 Docker 的由来、使用、优点和发展趋势&#xff0c;但对…