当前位置: 首页 > news >正文

SpringBoot源码(1)ApplicationContext和BeanFactory

1、调用getBean方法

@SpringBootApplication
public class SpringBootDemoApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);applicationContext.getBean("1");}
}

先创建ConfigurableApplicationContext对象,然后调用getBean方法

ctrl+alt+u:显示类图

在这里插入图片描述

BeanFactory是ApplicationContext的父接口,BeanFactory是容器的核心接口,ApplicationContext是提供组合

在这里插入图片描述

getBean方法会先获取BeanFactory对象,然后调用BeanFactory对象的getBean方法,不是ApplicationContext直接调用的getBean方法

在这里插入图片描述

在这里插入图片描述

创建的BeanFactory对象是DefaultListableBeanFactory类的对象,BeanFactory对象是保存在GenericApplicationContext类中的

在这里插入图片描述

实际创建DefaultListableBeanFactory容器对象,DefaultListableBeanFactory类实现了ConfigurableListableBeanFactory接口,ConfigurableListableBeanFactory接口继承了ListableBeanFactory接口,ListableBeanFactory接口继承了BeanFactory接口

在这里插入图片描述

调用DefaultListableBeanFactory对象的getBean方法,实际调用的是AbstractBeanFactory抽象类中的getBean方法

结论:DefaultListableBeanFactory类非常重要!!!它提供了IOC控制反转、DI依赖注入、Bean的生命周期

2、获取BeanFactory对象中所有的单例对象

需求:输出singletonObjects容器中所有的单例对象

在这里插入图片描述

DefaultSingletonBeanRegistry类是DefaultListableBeanFactory类的父类,DefaultSingletonBeanRegistry类中包含singletonObjects是单例对象容器,它是一个ConcurrentHashMap,它是一级缓存

@SpringBootApplication
@Log4j2
public class SpringBootDemoApplication {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);// 获取单例对象singletonObjectsClass<DefaultSingletonBeanRegistry> cls = DefaultSingletonBeanRegistry.class;Field field = cls.getDeclaredField("singletonObjects");field.setAccessible(true);// field.get(对象实例),对象是BeanFactory对象,// application.getBeanFactory()方法返回的是ConfigurableListableBeanFactory接口,实际返回的是DefaultListableBeanFactory类// DefaultListableBeanFactory类是DefaultSingletonBeanRegistry的子类,因此DefaultListableBeanFactory对象可以获取到DefaultSingletonBeanRegistry的属性DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();Map<String, Object> map = (Map<String, Object>) field.get(beanFactory);map.forEach((k, v) -> {log.info("k = {}, v = {}", k, v);});}
}

思路:利用反射获取容器中所有的单例对象,即属性.get(对象实例),singletonObjects容器在DefaultSingletonBeanRegistry类中,DefaultSingletonBeanRegistry对象如何获取呢?DefaultListableBeanFactory类是DefaultSingletonBeanRegistry类的子类,可以通过applicationContext.getBeanFactory()方法获取DefaultListableBeanFactory对象

3、ApplicationContext相比BeanFactory的扩展功能

ApplicationContext接口继承了BeanFactory接口,ApplicationContext对象封装了BeanFactory对象,并实现4种扩展功能

在这里插入图片描述

先点击类,然后点击F4可以跳转到指定类中

(1)MessageSource接口

在这里插入图片描述

MessageSource接口是用于国际化的,它包含getMessage方法可以选择指定code指定locale的语言值

在这里插入图片描述

其中,messages.properties是国际化的通用配置文件,它必须存在(可以不写内容)

message_zh.properties配置文件中填写menu.menuName.code=按钮

message_en.properties配置文件中填写menu.menuName.code=button

@SpringBootApplication
@Log4j2
public class SpringBootDemoApplication {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);String message = applicationContext.getMessage("menu.menuName.code", null, Locale.CHINA);log.info("中文:{}", message);message = applicationContext.getMessage("menu.menuName.code", null, Locale.ENGLISH);log.info("英文:{}", message);}
}

由于ApplicationContext接口继承了MessageSource接口,因此可以调用MessageSource接口的getMessage方法

在这里插入图片描述

输出结果是国际化语言值中文和英文

解析浏览器请求头的语言信息是LocaleResolver

(2)ResourcePatternResolver接口

在这里插入图片描述

ResourcePatternResolver类用来查找资源文件

@SpringBootApplication
@Log4j2
public class SpringBootDemoApplication {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);Resource[] resources = applicationContext.getResources("classpath:application.yml");Arrays.stream(resources).forEach(resource -> {log.info("resource: {}", resource);String filename = resource.getFilename();log.info("filename: {}", filename);});log.info("===========================================");resources = applicationContext.getResources("classpath*:META-INF/spring.factories");Arrays.stream(resources).forEach(resource -> {log.info("resource: {}", resource);String filename = resource.getFilename();log.info("filename: {}", filename);});}
}

寻找classpath类路径下的指定资源文件,比如找application.yml、META-INF/spring.factories

其中,classpath*:a.txt的*是查找jar包下的a.txt文件

在这里插入图片描述

共有3个地方有META_INF/spring.factories文件

(3)EnvironmentCapable接口

public interface EnvironmentCapable {/*** Return the {@link Environment} associated with this component.*/Environment getEnvironment();}

这个接口是获取环境变量的

@SpringBootApplication
@Log4j2
public class SpringBootDemoApplication {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);ConfigurableEnvironment environment = applicationContext.getEnvironment();String javaHome = environment.getProperty("java_home");log.info("Java home: " + javaHome);String serverPort = environment.getProperty("server.port");log.info("Server port: " + serverPort);}
}

调用getEnvironment方法和getProperty方法获取环境变量

在这里插入图片描述

结果是获取得到环境变量包括application.yml

(4)ApplicationEventPublisher接口

在这里插入图片描述

事件用来解耦的,ApplicationEventPublisher接口定义了publishEvent方法可以发布事件

public class UserLoginApplicationEvent extends ApplicationEvent {public UserLoginApplicationEvent(Object source) {super(source);}
}

1、定义事件:先定义事件UserLoginApplicationEvent,它要继承ApplicationEvent抽象类

@SpringBootApplication
@Log4j2
public class SpringBootDemoApplication {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringBootDemoApplication.class, args);applicationContext.publishEvent(new UserLoginApplicationEvent(applicationContext));}
}

2、发布事件:调用publishEvent方法,参数是创建一个UserLoginApplicationEvent事件,source是applicationContext,当然可以在一个对象中注入ApplicationEventPublisher或者ApplicationContext接口然后调用publishEvent方法发布事件

@Component
@Log4j2
public class UserLoginApplicationListener implements ApplicationListener<UserLoginApplicationEvent> {@Overridepublic void onApplicationEvent(UserLoginApplicationEvent event) {log.info("UserLoginApplicationListener received event: " + event);}
}

3、监听事件:第1种方式是定义一个类接收事件,必须注入到容器中,监听器必须实现ApplicationListener接口,指定泛型是UserLoginApplicationEvent事件,重写onApplicationEvent方法

@Component
@Log4j2
public class UserLoginListener {@EventListenerpublic void receivedEvent(UserLoginApplicationEvent event) {log.info("UserLoginListener received event: {}", event);}}

3、监听事件:第2种方式是创建一个public void方法,入参是事件,方法用注解@EventListener来监听事件

在这里插入图片描述

测试结果是启动服务会发布事件,两个监听器都会收到事件并输出,并且实现ApplicationListener接口的方式比方法用注解@EventListener来监听事件的方式先执行

相关文章:

SpringBoot源码(1)ApplicationContext和BeanFactory

1、调用getBean方法 SpringBootApplication public class SpringBootDemoApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext SpringApplication.run(SpringBootDemoApplication.class, args);applicationContext.get…...

CANoe编程实例--TCP/IP通信

1、简介 本实例将使用目前常用的开发工具C#来开发服务器端&#xff0c;以CANoe端作为客户端。服务器端和客户端&#xff0c;通过TCP/IP连接&#xff0c;实现数据交换。 首先在服务器端建立一个监听Socket&#xff0c;自动创建一个监听线程&#xff0c;随时监听是否有客户端的连…...

Neuron协议网关的北向应用插件开发

目录 概述 指令处理层开发​ 应用层开发​ .open​ .close​ .init​ .uninit​ .start​ .stop​ .setting​ .request​ 插件设置文件​ 适配华为的思路 概述 最近研究了一段时间的Neuron协议网关&#xff0c;前面的博文也提到它虽然能够把数据发到华为的IoT平台上…...

【BUG】已解决:You are using pip version 10.0.1, however version 21.3.1 is available.

You are using pip version 10.0.1, however version 21.3.1 is available. 目录 You are using pip version 10.0.1, however version 21.3.1 is available. 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#…...

electron-builder打包vue2项目不显示element-ui图标

1、使用版本 vue ^2.6.14element-ui ^2.15.14vue-cli-plugin-electron-builder 2.1.1 2、解决办法 1&#xff09; 如果是简单的图标可以使用图片代替&#xff08;这种对于elementui组件的图标还是不会显示&#xff09; 2&#xff09;在vue.config.js配置 const { defineCon…...

controller层-请求格式为json-请求方法为get

前置条件 get请求映射&#xff0c;内容和PostMapping一致&#xff0c;需要请求参数更换为get数据 请求过程&#xff1a;用户请求--初始化DispatcherServlet及对接和分发用户请求--controller--service 用户请求&#xff1a;http://ip:port/user/getinfo 请求方法&#xff1a;ge…...

【Linux】网络通信基础:应用层协议、HTTP、序列化与会话管理

文章目录 前言1. 应用层自定义协议与序列化1.1 什么是应用层&#xff1f;1.2 再谈 "协议"1.3 序列化 和 反序列化 2. HTTP 协议3. 认识 URL(统一资源定位符)4. urlencode和urldecode5. HTTP 协议请求与响应格式5.1 HTTP 请求5.2 HTTP 响应 6. HTTP 的方法6.1 GET 方法…...

@NotNull、@NotEmpty 和 @NotBlank 区别

NotNull、NotEmpty 和 NotBlank 是 Java Bean Validation (JSR 380) 规范中定义的注解&#xff0c;通常用于验证对象的属性是否满足特定的条件。这些注解常用于后端验证&#xff0c;确保接收到的数据符合预期。 NotNull 用途&#xff1a;验证一个对象是否不为null。 注意&#…...

大模型应用—大模型赋能网络爬虫

大模型赋能网络爬虫 简单来说,网页抓取就是从网站抓取数据和内容,然后将这些数据保存为XML、Excel或SQL格式。除了用于生成潜在客户、监控竞争对手和市场研究外,网页抓取工具还可以用于自动化你的数据收集过程。 借助AI网页抓取工具,可以解决手动或纯基于代码的抓取工具的…...

在 Qt 中获取 MouseMove 事件

在编写 Qt 程序时&#xff0c;我希望在鼠标移动时&#xff08;即使鼠标在另一个窗口上&#xff09;能够调用 mouseMoveEvent(QMouseEvent* event) 方法。目前&#xff0c;在我的 mainwindow.cpp 文件中&#xff0c;我有如下代码&#xff1a; void MainWindow::mouseMoveEvent(…...

自动驾驶系列—智能巡航辅助功能中的路口通行功能介绍

自动驾驶系列—智能巡航辅助功能中的车道中央保持功能介绍 自动驾驶系列—智能巡航辅助功能中的车道变换功能介绍 自动驾驶系列—智能巡航辅助功能中的横向避让功能介绍 自动驾驶系列—智能巡航辅助功能中的路口通行功能介绍 文章目录 2. 功能定义3. 功能原理4. 传感器架构5. 实…...

如何为WordPress网站设置多语言站点

随着全球化的发展&#xff0c;拥有一个支持多语言的站点已成为提升用户体验、扩大受众范围的重要手段。本文将详细介绍如何为WordPress网站设置多语言站点&#xff0c;提供两种最佳方案详解&#xff0c;帮助您轻松实现多语言站点的搭建与管理。无论您是选择在同一站点内发布多语…...

【RHCE】综合真机实验(shell完成)

目录 题目&#xff1a; 需求描述 实操 一、服务端&#xff08;servera&#xff09; 1.ip配置 2.更改主机名 3.创建本地仓库 4.DNS服务 1.下载软件包和防火墙允许 2.配置主配置文件 3.配置区域文件 1.named.exam 2.named.fangxiang 4.重启服务 5.验证结果&#x…...

【Python】成功解决conda创建虚拟环境时出现的CondaHTTPError: HTTP 000 CONNECTION FAILED错误

【Python】成功解决conda创建虚拟环境时出现的CondaHTTPError: HTTP 000 CONNECTION FAILED错误 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&a…...

苹果笔记本电脑如何优化系统 苹果电脑系统优化软件哪个好 cleanmymac x怎么用

随着时间的推移&#xff0c;你可能会发现你的MacBook运行速度变慢&#xff0c;甚至在执行一些基本任务时也会感觉到卡顿。这不仅影响了工作效率&#xff0c;也大大降低了使用体验。但别担心&#xff0c;优化你的Mac系统比做早餐还简单。本文将用一种轻松的风格向你介绍7种简单易…...

Vue数组操作之sort详解

在 Vue.js 中&#xff0c;sort() 方法用于对数组进行排序。它会改变原数组&#xff0c;并返回排序后的数组。默认情况下&#xff0c;sort() 方法按照字母顺序&#xff08;Unicode 编码顺序&#xff09;对数组中的元素进行排序。如果需要按照其他规则排序&#xff0c;可以传递一…...

解决 Android 应用安装错误:INSTALL_FAILED_BAD_PERMISSION_GROUP

解决 Android 应用安装错误&#xff1a;INSTALL_FAILED_BAD_PERMISSION_GROUP 在开发 Android 应用时&#xff0c;我们有时会遇到安装错误。这篇文章将讨论一种常见的错误&#xff1a;INSTALL_FAILED_BAD_PERMISSION_GROUP&#xff0c;并介绍解决方法。 问题描述 在尝试安装…...

浅谈断言之JSON断言

浅谈断言之JSON断言 JSON断言是Apache JMeter中一个非常实用的功能&#xff0c;它允许用户验证HTTP响应中的JSON数据是否符合预期。这对于API测试尤为重要&#xff0c;因为JSON&#xff08;JavaScript Object Notation&#xff09;是Web服务间通信的常用数据格式。通过精确地检…...

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(四)-无人机认证与授权

引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everything&#xff09;服务的支持。 3GPP TS 23.256 技术规范&#xff1a; 【免费】3GPPTS23.256技术报告-无人机系…...

1万+台网络设备运维如何选择支撑工具?

针对1万台网络设备的运维管理&#xff0c;需要采取一套系统化、自动化且高效的管理方法与策略。“工欲善其事&#xff0c;必先利其器”&#xff0c;以下结合一些关键步骤探讨运维支撑软件工具的方案。 1 建立完善的设备档案 设备信息记录&#xff1a; 为每台设备建立详细的…...

保姆级教程:在CentOS 7上用达梦8搭建DCA练习环境(附ulimit、VNC、ODBC全配置)

达梦8 DCA认证实战&#xff1a;CentOS 7环境搭建与调优全指南 在国产数据库技术快速发展的今天&#xff0c;达梦数据库作为核心产品之一&#xff0c;其DCA认证已成为众多从业者提升竞争力的重要选择。与理论为主的认证不同&#xff0c;DCA更注重实际操作能力&#xff0c;而一个…...

Hirschmann RS20-0800M4M4SDAE工业以太网交换机

Hirschmann RS20-0800M4M4SDAE 工业以太网交换机产品特点&#xff1a;端口配置&#xff1a;共8个端口&#xff0c;含6个RJ45电口和2个ST光纤接口。端口速率&#xff1a;所有端口均为100Mbps快速以太网。光纤类型&#xff1a;2个光纤端口为多模、ST接头。管理类型&#xff1a;二…...

PDF 可视化签名盖章页技术解析

本文是我在设备检测系统项目开发中,无设备检测的技术实现备忘录,记载实现过程。 本文以 PC 端页面 sign-pdf.vue 为主线,说明「无设备报检」在报告审批环节如何通过前后端协作,完成报告/记录 PDF 上的签名、印章、报告编号拖放定位,并在审批通过后由后端合并生成带签章的正…...

基于可解释机器学习的城市人口流动空间降尺度分析实践

1. 项目概述&#xff1a;从宏观到微观&#xff0c;解码城市脉搏在城市的肌理中&#xff0c;人口的流动如同血液的循环&#xff0c;承载着经济活力、社会互动与空间结构的全部信息。无论是城市规划师优化公交线路&#xff0c;还是商业分析师评估店铺选址&#xff0c;亦或是公共卫…...

构建智能音乐档案:SoundCloud Downloader 的技术架构与实现哲学

构建智能音乐档案&#xff1a;SoundCloud Downloader 的技术架构与实现哲学 【免费下载链接】scdl Soundcloud Music Downloader 项目地址: https://gitcode.com/gh_mirrors/sc/scdl 在流媒体音乐主导的时代&#xff0c;音乐爱好者面临着一种矛盾&#xff1a;我们享受着…...

GEP协议深度解读:AI智能体自我进化的基因工程

OpenAI 官宣全面支持MCP协议,标志着AI应用架构的"连接标准"已定。如果说MCP是AI时代的USB-C,解决了模型与工具的连接问题,那么GEP(Genome Evolution Protocol,基因组进化协议)则正在解决另一个更本质的问题——智能体的自我进化与生命周期管理。 作为下一代AI基…...

Visual C++运行库一键安装指南:彻底解决Windows应用依赖问题

Visual C运行库一键安装指南&#xff1a;彻底解决Windows应用依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过打开软件时弹出"缺少…...

地理空间机器学习库全解析:从TorchGeo到Raster Vision的实战指南

1. 项目概述&#xff1a;为什么我们需要专门的地理空间机器学习库&#xff1f;如果你尝试过用标准的PyTorch或TensorFlow去处理一张卫星影像&#xff0c;大概率会在第一步就卡住。不是模型写不出来&#xff0c;而是数据根本读不进去&#xff0c;或者读进去了却对不上位置。一张…...

Midjourney V6锐化失控?3步诊断+5组--sref/--stylize协同参数公式,立竿见影修复模糊与锯齿

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney V6锐化失控的本质归因 Midjourney V6 引入的全新扩散架构与隐式细节增强机制&#xff0c;导致图像生成过程中高频纹理被过度强化&#xff0c;其根本原因并非参数误配&#xff0c;而是模型在…...

2026年新能源人才全球本地化策略

导读&#xff1a;报告基于领英行业洞察&#xff0c;聚焦 2026 年全球新能源行业发展格局、中国企业出海现状、人才供需痛点及全球化人才本地化落地策略&#xff0c;为新能源企业海外人才招聘、培养与组织管理提供完整解决方案。关注公众号&#xff1a;【互联互通社区】&#xf…...