Spring底层原理学习笔记--第二讲--(BeanFactory实现与ApplicaitonContext实现)
BeanFactory实现
package com.lucifer.itheima.a02;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Slf4j
public class TestBeanFactory {public static void main(String[] args) {// 刚开始创建好,内部没有任何的beanDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();//所以需要添加 bean 的定义(bean的定义有哪些特征:class(类型),scope,初始化,销毁),beanFactory根据bean的定义去创建bean的对象AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();beanFactory.registerBeanDefinition("config",beanDefinition);//给 BeanFactory 添加一些常用的后处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);//BeanFactory 后处理器主要功能,补充了一些bean定义beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));// for (String name: beanFactory.getBeanDefinitionNames()) {
// //输出结果为
// //config
// //org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// //org.springframework.context.annotation.internalAutowiredAnnotationProcessor
// //org.springframework.context.annotation.internalCommonAnnotationProcessor
// //org.springframework.context.event.internalEventListenerProcessor
// //org.springframework.context.event.internalEventListenerFactory
// //bean1
// //bean2
//
// // 如果没有
// // AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
// // beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach
// // (beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
// //没有这两句的话,输出结果为
// //config
// System.out.println(name);
// }
//
// // 输出结果为 14:22:55.758 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()
// //null
// //.getBean(Bean1.class)会创建bean1,所以会调用它的构造方法,打印了 构造 Bean1()
// //.getBean2()的时候打印的是null,也就是依赖注入的功能没有生效
// System.out.println(beanFactory.getBean(Bean1.class).getBean2());// Bean 后处理器,针对bean的生命周期的各个阶段提供扩展,例如 @Autowired @Resource...beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);for (String name: beanFactory.getBeanDefinitionNames()) {//输出结果为//config//org.springframework.context.annotation.internalConfigurationAnnotationProcessor//org.springframework.context.annotation.internalAutowiredAnnotationProcessor//org.springframework.context.annotation.internalCommonAnnotationProcessor//org.springframework.context.event.internalEventListenerProcessor//org.springframework.context.event.internalEventListenerFactory//bean1//bean2System.out.println(name);}// // 输出结果为
// //14:47:12.014 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()
// //14:47:12.023 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean2()
// System.out.println(beanFactory.getBean(Bean1.class).getBean2());beanFactory.preInstantiateSingletons();//准备好所有单例//输出结果为// 14:53:51.891 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean1()// 14:53:51.900 [main] INFO com.lucifer.itheima.a02.TestBeanFactory - 构造 Bean2()// ============================System.out.println("============================");
// System.out.println(beanFactory.getBean(Bean1.class).getBean2());// 输出 com.lucifer.itheima.a02.TestBeanFactory$Bean3@55a1c291System.out.println(beanFactory.getBean(Bean1.class).getInter());/*学到了什么a. beanFactory 不会做的事1.不会主动调用BeanFactory后处理器2.不会主动添加Bean后处理器3.不会主动初始化单例4.不会解析beanFactory 还不会解析 ${}与#{}b. bean后处理器会有排序的逻辑*/}@Configurationstatic class Config {@Beanpublic Bean1 bean1() {return new Bean1();}@Beanpublic Bean2 bean2() {return new Bean2();}@Beanpublic Bean3 bean3() {return new Bean3();}@Beanpublic Bean4 bean4() {return new Bean4();}}interface Inter {}static class Bean3 implements Inter {}static class Bean4 implements Inter {}static class Bean1 {public Bean1() {log.info("构造 Bean1()");}@Autowiredprivate Bean2 bean2;public Bean2 getBean2() {return bean2;}@Autowired // 注入的是bean3 按类型注入 如果如果有多个类型一样的话,看成员变量的名字,这里名字是bean3,所以注入的是bean3
// @Resource(name = "bean4") //注入的是bean4,因为指定了名字// 如果@Autowired注解和 @Resource(name = "bean4")注解同时存在的话,生效的是bean3,跟后处理器的顺序有关 @Autowired后置处理器优先级高于@Resource的,所以// @Autowired的先解析了private Inter bean3;public Inter getInter() {return bean3;}}static class Bean2 {public Bean2() {log.info("构造 Bean2()");}}
}
ApplicaitonContext实现
package com.lucifer.itheima.a02;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.Controller;@Slf4j
public class A02Application {public static void main(String[] args) {//输出结果为//bean1//bean2//com.lucifer.itheima.a02.A02Application$Bean1@23fe1d71testClassPathXmlApplicationContext();testFileSystemXmlApplicationContext();//输出结果为//读取之前...//读取之后...//bean1//bean2DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();System.out.println("读取之前...");for (String name:beanFactory.getBeanDefinitionNames()){System.out.println(name);}System.out.println("读取之后...");XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);reader.loadBeanDefinitions(new ClassPathResource("b01.xml"));// 如果是FileSystemXmlApplicationContext()//reader.loadBeanDefinitions(new FileSystemResource("src\\main" +"\\resources\\b01.xml"));for (String name: beanFactory.getBeanDefinitionNames()) {System.out.println(name);}//输出结果为//a02Application.Config//bean1//bean2//com.lucifer.itheima.a02.A02Application$Bean1@7adda9cctestAnnotationConfigurationContext();// testAnnotationConfigServletWebServerApplicationContext();}// 较为经典的容器,基于classpath下xml格式的配置文件来创建private static void testClassPathXmlApplicationContext() {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("b01.xml");for (String name: context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(context.getBean(Bean2.class).getBean1());}// 基于磁盘路径下xml格式的配置文件来创建private static void testFileSystemXmlApplicationContext() {
// FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("D:\\DemoProject\\MyAccessSdk" +
// "\\access\\src\\main" +
// "\\resources\\b01.xml");FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src\\main" +"\\resources\\b01.xml");for (String name: context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(context.getBean(Bean2.class).getBean1());}// 较为经典的容器,基于java配置类来创建private static void testAnnotationConfigurationContext() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);for (String name: context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(context.getBean(Bean2.class).getBean1());}// 较为经典的容器,基于java配置类来创建,用于web环境private static void testAnnotationConfigServletWebServerApplicationContext() {AnnotationConfigServletWebServerApplicationContext context =new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);}@Configurationstatic class WebConfig {@Beanpublic ServletWebServerFactory servletWebServerFactory() {return new TomcatServletWebServerFactory();}@Beanpublic DispatcherServlet dispatcherServlet(){return new DispatcherServlet();}@Beanpublic DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){return new DispatcherServletRegistrationBean(dispatcherServlet,"/");}@Bean("/hello")public Controller controller1(){return (request, response) -> {response.getWriter().println("hello");return null;};}}@Configurationstatic class Config{@Beanpublic Bean1 bean1() {return new Bean1();}@Beanpublic Bean2 bean2(Bean1 bean1) {Bean2 bean2 = new Bean2();bean2.setBean1(bean1);return bean2;}}static class Bean1 {}static class Bean2 {private Bean1 bean1;public void setBean1(Bean1 bean1) {this.bean1 = bean1;}public Bean1 getBean1() {return bean1;}}}
相关文章:
Spring底层原理学习笔记--第二讲--(BeanFactory实现与ApplicaitonContext实现)
BeanFactory实现 package com.lucifer.itheima.a02;import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.fac…...
云原生|kubernetes |kubelet服务加入系统守护进程supervisor(centos7系统下演示通过)
前言: kubelet 是 Kubernetes 集群中的一个重要组件,运行在每个节点上,负责管理该节点上的容器和Pod。它与控制平面(如 API Server 和 kube-controller-manager)通信,确保节点上的容器与期望的状态保持一致…...

onnx 模型加载部署运行方式
1.通过文件路径的onnx模型加载方式: 在onnxruntime下面的主要函数:session Ort::Session(env, w_modelPath.c_str(), sessionOptions); 这里的文件路径是宽字节的,通过onnx文件路径直接加载模型。 在opencv下使用dnn加载onnx模型的主要函数: std::string model…...

第68讲:MySQL触发器的核心概念以及常见的触发类型应用案例
文章目录 1.触发器的概念2.触发器操作的语法结构3.各类触发器的典型应用案例3.1.需求描述以及实现思路3.2.创建日志表3.3.INSERT类型的触发器3.4.UPDATE类型的触发器3.5.DELETE类型的触发器 1.触发器的概念 触发器是与表中数据相关的数据库对象,当表中的数据产生in…...

VS Code 开发 Spring Boot 类型的项目
在VS Code中开发Spring Boot的项目, 可以导入如下的扩展: Spring Boot ToolsSpring InitializrSpring Boot Dashboard 比较建议的方式是安装Spring Boot Extension Pack, 这里面就包含了上面的扩展。 安装方式就是在扩展查找 “Spring Boot…...

数据中心加密:保障数据安全的重要一环
随着信息化的快速发展,数据已经成为企业的重要资产,数据安全也成为了企业面临的重大挑战。数据中心作为企业数据存储和管理的重要场所,其安全性对于整个企业的数据安全具有至关重要的作用。而数据中心加密则是保障数据安全的重要一环。本文将…...

分享90个节日庆典PPT,总有一款适合您
分享90个节日庆典PPT,总有一款适合您 PPT下载链接:百度网盘 请输入提取码 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集整理更不易。知识付费甚欢喜,为咱码农谋福利…...

Python Faker批量生成测试数据
一、前言 在做自动化测试或压力测试时会需要大批量生成测试数据,简单的方式你可以写一个存储过程使用随机函数来生成记录,但这种生成数据看起来不够真实,其实有蛮多现成的工具可以完成这一任务。 二、Faker基本使用介绍 faker是一个生成伪…...
Docker-compose 运行MySQL 连接不上
Docker-compose 运行MySQL 连接不上 📔 千寻简笔记介绍 千寻简笔记已开源,Gitee与GitHub搜索chihiro-notes,包含笔记源文件.md,以及PDF版本方便阅读,且是用了精美主题,阅读体验更佳,如果文章对你有帮助请帮我点一个Star~ 更新:支持在线阅读文章,根据发布日期分类…...

Educational Codeforces Round 2 D 计算几何
题目链接:Educational Codeforces Round 2 D 题目 给你两个圆。求它们相交处的面积。 输入 第一行包含三个整数 x1, y1, r1 ( - 109 ≤ x1, y1 ≤ 109, 1 ≤ r1 ≤ 109 ) - 第一个圆的圆心位置和半径。 第二行包含三个整数 x2, y2, r2 ( …...
hexo博客发布换电脑换地方了怎么办?
假如你有2台MacBook,一台在家,一台在公司。在家的hexo本地环境都搭好了,markdown文件等等也都放在本地source下的_posts文件夹里了。但是我过2天又想有个新文章发布,这时候电脑在公司,那么该怎么办? 把家里…...

最新知识付费变现小程序源码/独立后台知识付费小程序源码/修复登录接口
最新知识付费变现小程序源码,独立后台知识付费小程序源码,最新版修复登录接口。 主要功能 会员系统,用户登录/注册购买记录 收藏记录 基本设置 后台控制导航颜色 字体颜色 标题等设置 流量主广告开关小程序广告显示隐藏 广告主审核过审核…...

奥威BI软件 | 职场人的数据可视化救星
对时间紧张、工作繁重的职场人来说,一款易学易用、效率高、数据展现直观的数据可视化软件必不可少。奥威BI软件就是这样一款数据可视化软件,零编程开发报表,不需要额外多花时间,即可点击、拖拉拽完成数据分析、报表制作࿰…...
最长公共前缀[简单]
优质博文:IT-BLOG-CN 一、题目 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串""。 示例 1: 输入:strs ["flower","flow","flight"] 输出…...
Java后端开发(十一)-- Mysql8的详细安装与环境配置
目录 1. mysql数据库下载 官网在线下载 2. 下载 MySQL的安装包 3. 安装MySQL...

什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
🧸欢迎来到dream_ready的博客,📜相信您对这几篇博客也感兴趣o (ˉ▽ˉ;) 📜什么是SpringMVC?简单好理解!什么是应用分层?SpringMVC与应用分层的关系? 什么是三层架构&…...
PyTorch 从tensor.grad 看 backward(权重参数) 和 gradient accumulated
1. 新建一个自变量 tensor x import torchx torch.ones(1, requires_gradTrue) print(x)1. 输出: tensor([1.], requires_gradTrue)2. 写一个 forward import torchx torch.ones(1, requires_gradTrue) y x**2 z x**33. y, z 都 backward import torchx to…...
fedora 命令行代理proxychains 使用flatpak下载 flathub包
feodra 28 有 tsocks - (rpm 包)工具, 后面就没有了. 不过还有替代工具 proxychains 当前操作环境 Fedora 38 proxychains 配置文件所在位置 # 全局配置 /etc/proxychains.confproxychains looks for configuration in the following order: SOCKS5 proxy port in environme…...
介绍kamailio的dialog模块
# 介绍kamailio的dialog模块 kamailio的dialog模块一般有四个作用: - 读写对话变量 - 跟uac模块配合,完成uac trunk auth功能 - 统计early_dialogs和active_dialogs等 - 利用dialog profile实现分类统计功能或者实现呼叫限制功能 dialog模块的参数可以…...

性能优于BERT的FLAIR:一篇文章入门Flair模型
文章目录 What is FLAIR?FLAIR ModelContextual String Embedding for Sequence Labelingexample FLAIR Application AreaSentiment AnalysisNamed Entity RecognitionText Classification FLAIR一、什么是FLAIR?二、FLAIR Library的优势是什么ÿ…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...