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, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
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…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
