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的优势是什么ÿ…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
理想汽车5月交付40856辆,同比增长16.7%
6月1日,理想汽车官方宣布,5月交付新车40856辆,同比增长16.7%。截至2025年5月31日,理想汽车历史累计交付量为1301531辆。 官方表示,理想L系列智能焕新版在5月正式发布,全系产品力有显著的提升,每…...
React 样式方案与状态方案初探
React 本身只提供了基础 UI 层开发范式,其他特性的支持需要借助相关社区方案实现。本文将介绍 React 应用体系中样式方案与状态方案的主流选择,帮助开发者根据项目需求做出合适的选择。 1. React 样式方案 1.1. 内联样式 (Inline Styles) 通过 style …...
