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来监听事件的方式先执行

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

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

相关文章

Java强软弱虚引用的特点以及应用场景(面试重点)

强&#xff1a;即使OOM也不回收软&#xff1a;内存溢出前回收弱&#xff1a;只要垃圾收集就死虚&#xff1a;对垃圾收集没关系&#xff0c;只有得到通知&#xff08;插眼&#xff0c;也操作不了对象、只能看到它还活着&#xff09; 一、软引用 代码示例&#xff1a; public cl…

【C++开源】GuiLite:超轻量UI框架-入门

开发环境说明 使用visual Studio 2022进行开发 下载源码 从如下的网址进行源码和示例代码的下载: GitHub源码网址为:idea4good/GuiLite示例代码路径为:idea4good/GuiLiteExample使用方法 GuiLite是一个仅有头文件的一个库,使用的时候直接include到自己的UIcode.cpp文件…

十七、(正点原子)Linux LCD驱动

一、Framebuffer设备 在 Linux 中应用程序通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。 先来看一下裸机 LCD 驱动如下&#xff1a; ①、初始化 I.MX6U 的 eLCDIF 控制器&#xff0c;重点是 LCD 屏幕宽(width)、高(height)、 hspw、 hbp、 hfp、 vspw…

【Python】连接MySQL数据库:详细教程与示例代码

文章目录 1. 安装必要的库2. 建立与MySQL的连接3. 执行SQL查询4. 插入数据5. 更新数据6. 删除数据7. 错误处理8. 小结 在数据驱动的开发中&#xff0c;连接数据库是一个至关重要的技能。Python作为一门强大的编程语言&#xff0c;提供了多种方式连接并操作MySQL数据库。本文将详…

【时时三省】(C语言基础)函数和数组

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 函数 跟数学里面的函数很相似 数组 一组相同类型的元素的集合 比如把5个整形1-5存起来 int arr&#xff3b;10&#xff3d;&#xff1d;&#xff5b;1&#xff0c;2&#xff0c;3&#x…

浏览器打开抽奖系统html

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>在线抽奖 随机选取 自动挑选</title> <script src"https://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script> <style> body {…

antdesgin table 组件下载成excel

文章目录 发现宝藏一、需求二、报错 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 一、需求 原组件如下&#xff0c;需要添加下载功能 import React, { useState } from rea…

Spring Boot + Spring Cloud 入门

运行配置 java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --spring.profiles.activetest --my1.age32 --debugtrue "D:\Program Files\Redis\redis-server.exe" D:\Program Files\Redis\redis.windows.conf "D:\Program Files\Redis\redis-cli.exe" &q…

Go语言 Import导入

本文主要介绍Go语言import导入使用时注意事项和功能实现示例。 目录 Import 创建功能文件夹 加法 减法 主函数 优化导入的包名 .引入方法 总结 Import 创建功能文件夹 做一个计算器来演示&#xff0c;首先创建test文件夹。 加法 在test文件夹中创建add文件夹&#xff…

《简历宝典》17 - 简历中“技术能力”,如何丰满且有层次,前端篇

这一节开始对技术能力模块做讲解&#xff0c;我们身边的这些互联网IT从业者们&#xff0c;前端开发、Java开发、软件测试又或者是其他职位的开发者们&#xff0c;技术能力这个模块是绕不过去的&#xff0c;从简历上看&#xff0c;这个模块体现了我们之前软件工作生涯中的技术功…

大厂面试-基本功

大厂面试第4季 服务可用性多少个9是什么意思遍历集合add或remove操作bughashcode冲突案例BigdecimalList去重复IDEA Debugger测试框架ThreaLocal父子线程数据同步 InheritableThreadLocal完美解决线程数据同步方案 TransmittableThreadLocal 服务可用性多少个9是什么意思 遍历集…

【C++高阶】哈希函数底层原理探索:从算法设计到实现优化

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;模拟实现 map与set &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀哈希 &#x1f4da;1. unord…

(ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类

文章目录 Robust deep alignment network with remote sensing knowledge graph for zero-shot and generalized zero-shot remote sensing image scene classification相关资料摘要引言遥感知识图谱的表示学习遥感知识图谱的构建实体和关系的语义表示学习创建遥感场景类别的语…

ts踩坑!vue3中ts文件用export导出公共方法的ts类型定义

当我们有一个ts文件&#xff0c;定义并export出该function&#xff0c;其中方法里边有定义的变量&#xff0c;方法、钩子函数等多种&#xff0c;并最终return出该变量、方法。 此时 ts规则校验会让我们返回该函数类型。如下 export default function () {const chart ref();c…

Java基础-序列化、泛型、1.8新特性、其他

目录 序列化 什么是序列化&#xff1f;什么是反序列化&#xff1f; Serializable 接口有什么用&#xff1f; serialVersionUID 又有什么用&#xff1f; Java 序列化不包含静态变量吗&#xff1f; 如果有些变量不想序列化&#xff0c;怎么办&#xff1f; 说说有几种序列化…

Yolo-World网络模型结构及原理分析(一)——YOLO检测器

文章目录 概要一、整体架构分析二、详细结构分析YOLO检测器1. Backbone2. Head3.各模块的过程和作用Conv卷积模块C2F模块BottleNeck模块SPPF模块Upsampling模块Concat模块 概要 尽管YOLO&#xff08;You Only Look Once&#xff09;系列的对象检测器在效率和实用性方面表现出色…

计网:物理层

写在开头&#xff1a;物理层就负责传送比特0和1&#xff0c; 本质上理解物理层就是理解传输介质哪个表示比特0和1&#xff0c;如&#xff1a;高电平表示1、低电平表示0等 物理层主要任务&#xff1a; 机械特性&#xff1a;指明接口所用接线器的形状和尺寸、引脚数目和排列、固…

【BUG】已解决:requests.exceptions.ProxyError: HTTPSConnectionPool

已解决&#xff1a;requests.exceptions.ProxyError: HTTPSConnectionPool 目录 已解决&#xff1a;requests.exceptions.ProxyError: HTTPSConnectionPool 【常见模块错误】 原因分析 解决方案 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&am…

Android Studio 输出信息出现乱码

现象 解决办法 一、第一步 二、第二步 添加如下代码&#xff1a; 直接复制进去即可 -Dfile.encodingUTF-8 注意 &#xff1a;最后&#xff0c;添加后重新编译工程&#xff0c;如果还是发现乱码&#xff0c;则需要关闭Android Studio重新启即可

Spring Security之安全异常处理

前言 在我们的安全框架中&#xff0c;不管是什么框架&#xff08;包括通过过滤器自定义&#xff09;都需要处理涉及安全相关的异常&#xff0c;例如&#xff1a;登录失败要跳转到登录页&#xff0c;访问权限不足要返回页面亦或是json。接下来&#xff0c;我们就看看Spring Sec…