【springboot原理篇】Bean的加载方式,面试必看

🌈键盘敲烂,年薪30万🌈

目录

一、上古时代原始方式:

📕XML文件

~~bean定义

👀演示获取bean:

❌缺点:

📕注解方式:

~~@component

~~指定扫描路径:

👀演示获取bean

📕XML太繁琐: 

二、现代科技配置类

🐟配置类作用:

🐟@componentScan

🐟@configuration

👀演示获取bean

⭐本文重点,没有之一⭐

三、工厂模式FactoryBean

📕认识它

📕factorybean的优势:

📕小总结

四、超级无敌@import

📕应用场景:

📕@importResource

❓思考问题:

📕@import({类的字节码文件,……})

📕@import导入ImprotSelector接口

📕@import导入ImportBeanDefinitionRegistrar接口

📕@import导入BeanDefinitionRefistryPostProcessor接口 

五、register注册bean

📕register

六、总结


一、上古时代原始方式:

📕XML文件
~~bean定义
  • 配置自己的或者第三方的bean:
  • id:指定bean的名称 class指定bean的位置
<!--声明自定义bean--><bean id="dog" class="com.itpan.domain.Dog"/><bean class="com.itpan.domain.Cat"/><!--声明第三方bean--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>

 

👀演示获取bean:
    void te1(){ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationcontext1.xml");System.out.println(ctx.getBean("dog")); // 获取自定义baenSystem.out.println(ctx.getBean(Cat.class));System.out.println(ctx.getBean("dataSource")); // 获取第三方bean//获取所有的beanSystem.out.println("================");for (String name : ctx.getBeanDefinitionNames()) {System.out.println(name);}}
❌缺点:

太麻烦,且可读性太差,bean一旦多了就不知道哪些被加载了,哪些没被加载。

📕注解方式:
~~@component
  • 只要在你的类上加上@component注解,就代表这个类要交给IOC容器管理
  • 但这还不够,java文件这么多,IOC不能所有文件都扫描一遍吧,所以还要在XML配置文件里面指定扫描路径。
  • component(value = "可指定bean的名称") 等同于z在XML里面的id
~~指定扫描路径:

开启命名空间需要动5个地方:

👀演示获取bean
    @Testvoid te2(){// 通过注解加载的beanClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationcontext2.xml");System.out.println(ctx.getBean("dog")); // 获取自己的beanSystem.out.println(ctx.getBean("dataSource")); // 获取第三方的beanSystem.out.println("===============");// 获取容器中的所哟beanfor (String name : ctx.getBeanDefinitionNames()) {System.out.println(name);}}
📕XML太繁琐: 

XML文件里面的内容都是固定的,只有bean的定义不同,那么能不能省区XML文件呢???

 

二、现代科技配置类

🐟配置类作用:

配置类说白了就是加载bean的,当然配置类本身也会变为bean(重要),只要在配置类上加相应的注解,spring会自动扫描相应的包来加载bean。

🐟@componentScan

@componentScan就替代了XML里面那一大坨代码,但是扫描哪些包spring还不知道,所以要指定包扫描路径:@component({"指定扫描哪些包下的bean","xxx"})。

小细节:如果不加扫描路径,默认扫描本包及其子包下的类。

🐟@configuration

同上面的注解一样,它亦可以代替XML文件,表示该类是一个配置类,但是它们两个真的相同吗?

👀演示获取bean
    @Testvoid te3(){AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig1.class);for (String name : ctx.getBeanDefinitionNames()) {System.out.println(name);}}

注意:

获取配置类的bean是通过annotationconfigapplicationcontext这个对象的相关方法,那么@cofiguration与@componentScan有什么不同吗,如果相同用为什么会出现两个注解。

 

⭐本文重点,没有之一⭐
  • 相同点:加上这两个注解都会将该类变为配置类,成为IOC容器的bean,假如你获取bean的方式为annotationconfigapplicationcontext,那么这两个注解的作用一样。
  • 但是,如果你加载bean的方式是通过别的包扫描这个包,那么你不加@configuration这个注解就扫描不上,扫描不上就成为不了bean对象,到时候就干瞪眼了。

@configuration这个注解有个属性是proxybeanmethods,它的作用是使用哪种代理模式。

看完下面这个例子你就懂了

运行结果:

把proxybeanmethod改为false:

总结:

        当proxybeanmethods为true是,调用里面的方法创建的bean是代理对象调用的,也就是每一次调用方法如果IOC容器俩面有这个bean对象,就会使用这个对象,如果没有,new一个,以后用到了就会返回这个对象,所有三个bean对象一致。

        当proxybeanmethods为false是,代理对象每一次调用创建bean的方法都不会从IOC容器里面找,而是直接跑一遍代码,从而导致创建的三个bean对象不一致。

三、工厂模式FactoryBean

📕认识它

FactoryBean是我们创建了一个类,这个类专门用来造bean的,你可能会有疑惑,它和上面直接返回这个对象的那种方法有什么区别啊?就像下面这样

📕factorybean的优势:

来自gpt的肯定:

FactoryBean 提供了更高级别的配置和创建过程的控制,允许你以更灵活的方式管理和定制 Bean 的创建。它适用于那些需要特殊处理的 Bean 创建场景,而不仅仅是简单地实例化和配置对象。

📕小总结

并不是你返回值是什么就创建什么bean,例如factorybean就是创建的它的泛型的bean

四、超级无敌@import

📕应用场景:

假如一个很老的项目已经打包上线了,加载bean的方式XML,现在要新增功能,如何添加新的将那些bean导入呢??你不能修改原码依次加上各种注解吧,这不现实。。

就像下面这样:

运行后只有spring自带的bean:

📕@importResource

你只需加上这么一个注解,指定文件路径就欧啦!!

再次运行,熟悉的bean就回来了

❓思考问题:

假如你的spring中也定义了Dog这个bean,引入的XML文件也定义了Dog,那么会发生什么

结论:

XML文件的bean会覆盖spring中的bean

📕@import({类的字节码文件,……})
  • 使用improt注解导入的bean无需在该bean上加@component注解,并且使用import导入的bean的名称为类全类名,不再是什么方法的返回值了,这点要注意
  • 如果导入的是配置类,不光配置类被加载为bean,配置类里面的bean也被加载为bean。
@Configuration(proxyBeanMethods = false)
@Import({Cat.class})
public class SpringConfig3 {@Beanpublic Dog dog(){return new Dog();}
}

注意:import只能使用一次,如果想导入多个bean,用,分割

📕@import导入ImprotSelector接口

可以做到bean的加载控制

public class MyImportSelect implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// import导谁,形参就是谁System.out.println("提示" + importingClassMetadata);// 优势就是可以在这里面做判断,做到bean的加载控制boolean flag = importingClassMetadata.hasAnnotation("import org.springframework.context.annotation.Configuration");if (flag){return new String[]{"com.itpan.domain.Cat"};}return new String[]{"com.itpan.domain.Fish"};}
}
📕@import导入ImportBeanDefinitionRegistrar接口

可以自定义bean的名称

public class MyRegister implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {// 构造一个beandefinition对象BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Fish.class).getBeanDefinition();registry.registerBeanDefinition("Jinyu", beanDefinition);}
}
📕@import导入BeanDefinitionRefistryPostProcessor接口 

当IOC容器初始化所有的bean后,在加载这个类中的bean,也叫bean的后处理。

public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {// bean的后处理@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}
}

五、register注册bean

📕register

容器初始化完成之后,可以手动注册bean

    @Testvoid te7(){AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig3.class);SpringConfig3 springConfig3 = ctx.getBean("springConfig3", SpringConfig3.class);System.out.println(springConfig3.dog());ctx.registerBean("cat", Cat.class);System.out.println(ctx.getBean("cat"));}

六、总结

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

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

相关文章

vm net 方式 静态ip配置访问主机IP和外网

1、win 11 安装vm&#xff0c;镜像文件 F:\software\VMwork\CentOS-7-x86_64-Everything-1804.iso 2、配置网络 net 方式 3、右击网络--》属性---》更改适配器设置--》vmnet8 属性 如果没有vm1、vm8 虚拟机编辑---》虚拟机网络编辑器-->还原默认设置 注意&#xff1a;这…

接口验签规则

一、验签的背景 在网络发展快速的过程中&#xff0c;总是会忽略接口数据安全问题&#xff0c;进行验签则能够在一定程度上能够防刷&#xff0c;数据篡改。 二、什么是加签验签 加签验签&#xff0c; 发送消息方&#xff0c;对消息加签名&#xff1b; 接受消息方&#xff0…

使用Notepad++编辑器,安装AnalysePlugin搜索插件

概述 是一款非常有特色的编辑器&#xff0c;Notepad是开源软件&#xff0c;Notepad中文版可以免费使用。 操作步骤&#xff1a; 1、在工具栏 ->“插件”选项。 2、勾选AnalysePlugin选项&#xff0c;点击右上角“安装”即可。 3、 确认安装插件 4、下载插件 5、插件已安装…

Java 设计模式——备忘录模式

目录 1.概述2.结构3.案例实现3.1.“白箱”备忘录模式3.2.”黑箱”备忘录模式 4.优缺点5.使用场景 1.概述 &#xff08;1&#xff09;备忘录模式 (Memento Pattern) 又称为快照模式&#xff0c;是一种行为型设计模式&#xff0c;它提供了一种保存和恢复对象状态的机制。备忘录模…

涓流充电计时电路芯片D1302,具有双管脚主电源和备用电源,可编程涓流充 电器VCC1,还有 31 字节的暂存器等功能

D1302 涓流充电计时电路包含一个实时时钟 / 日历和 31 字节的静 态RAM &#xff0c;通过简单的串行接口与微处理器通讯。这个实时时钟 / 日历 提供年月日、时分秒信息&#xff0c;对于少于31 天的月份月末会自动调整&#xff0c; 还有闰年校正。由于有一个 AM/PM 指示器&a…

天翼云:“百万IOPS”助推政企上云

随着数字化转型的加速&#xff0c;越来越多的企业选择了业务上云。众所周知&#xff0c;不论是政企关键/核心业务中的大型数据库、NoSQL、AI训练&#xff0c;还是互联网业务中的游戏、渲染等场景&#xff0c;对数据读写IOPS和时延有极高的要求。作为全球领先的云服务商&#xf…

分享77个菜单导航JS特效,总有一款适合您

分享77个菜单导航JS特效&#xff0c;总有一款适合您 77个菜单导航JS特效下载 链接&#xff1a;https://pan.baidu.com/s/1sfT9ONLH4ocliA1C7Z5xbQ?pwd6666 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0…

75Ω视频放大驱动芯片 D1671,2.8~5.5V 内 置 SAG端 子 6dB放 大 器 电 路,应用于手持设备中

D1671 是 一 块 带 4 级 低 通 滤 波 的 单 通 道 视 频 放 大 电 路 &#xff0c; 可 在 3V 或 5V的 低 电 压 下 工 作 。 该 电 路 用 在 有 TV 影 象 输 出 功 能 的 产 品 上 面 &#xff0c; 比 如 机 顶 盒 &#xff0c;监 控 摄 象 头 &#xff0c;DVD &#xf…

骨传导耳机音量大了有害吗?骨传导能保护听力吗?

无论是传统耳机还是骨传导耳机&#xff0c;只要使用音量过大&#xff0c;都会对有一定的损伤&#xff0c;然而由于骨传导耳机的传声原理和佩戴方式比较特殊&#xff0c;所以对人体的损伤比较小&#xff0c;想要知道骨传导耳机能否保护听力&#xff0c;就要先了解骨传导耳机的传…

【Axure教程】用中继器制作多选树

“多选树”可能指的是一种用户界面元素&#xff0c;用于展示层级结构并允许用户选择多个节点。这在软件应用程序中常用于设置、文件浏览器等场景。 Axure里面虽然自带了一个树元件&#xff0c;但是并没有多选的功能&#xff0c;所以今天就教大家如何用中继器制作一个多选树的基…

acwing-Linux学习笔记

acwing-Linux课上的笔记 acwing-Linux网址 文章目录 1.1常用文件管理命令homework作业测评命令 2.1 简单的介绍tmux与vimvimhomeworktmux教程vim教程homework中的一些操作 3 shell语法概论注释变量默认变量数组expr命令read命令echo命令printf命令test命令与判断符号[]逻辑运算…

Vue3集成ThreeJS实现3D效果,threejs+Vite+Vue3+TypeScript 实战课程【一篇文章精通系列】

Vue3集成ThreeJS实现3D效果&#xff0c;threejsViteVue3TypeScript 实战课程【一篇文章精通系列】 项目简介一、项目初始化1、添加一些依赖项 二、创建3D【基础搭建】1、绘制板子&#xff0c;立方体&#xff0c;球体2、材质和光照3、材质和光照和动画4、性能监控5、交互控制6、…

【有机化学(药学类)】醛和酮3

第一题 思考 格氏试剂与不饱和醛酮的亲核加成反应&#xff0c;主要发生1,2加成&#xff08;注意&#xff1a;氧原子算是1&#xff09; 第二题 思考 叶立德反应&#xff0c;看到磷原子就应该想到这个&#xff01; 第三题 思考 涉及到两个反应&#xff1a; 亲核加成反应&…

5. Jetson Orin Nano CUDA 配置

5. Jetson Orin Nano CUDA 配置 1&#xff1a;安装Jtop jtop安装主要有以下三个步骤&#xff1a; 安装pip3 我们需要使用pip3来安装jtop&#xff0c;所以先安装pip3 sudo apt install python3-pip安装jtop sudo -H pip3 install -U jetson-stats运行jtop服务 sudo -H pip3 in…

SAAS版专业级条码标签打印软件解决方案

一。新一代互联网打印模式 saas云标签打印软件支持条码、二维码、表格等模式组合打印&#xff0c;支持批量打印标签、表格模拟数据 、在线预览二维码打印 、在线条码生成打印标签 ● 条码/二维码/标签打印&#xff0c;支持表格批量打印标签&#xff1b; ● 条码/二维码尺寸…

每天一点python——day85

#每天一点Python——85 #python常见的异常类型&#xff1a; #如图&#xff1a; #①数学运算异常【由于会报错&#xff0c;我直接全部注释掉了】 print(10/0) 输出&#xff1a;ZeroDivisionError: division by zero#②索引错误list1[1,2,3,4] print(list1[5])#找索引为4的元素 输…

CUDA简介——同步

1. 引言 前序博客&#xff1a; CUDA简介——基本概念CUDA简介——编程模式CUDA简介——For循环并行化CUDA简介——Grid和Block内Thread索引CUDA简介——CUDA内存模式 本文重点关注Thread同步和Barriers。 Threads并行执行&#xff0c;可能存在如下问题&#xff1a; 1&#…

数学建模-基于集成学习的共享单车异常检测的研究

基于集成学习的共享单车异常检测的研究 整体求解过程概述(摘要) 近年来&#xff0c;共享单车的快速发展在方便了人们出行的同时&#xff0c;也对城市交通产生了一定的负面影响&#xff0c;其主要原因为单车资源配置的不合理。本文通过建立单车租赁数量的预测模型和异常检测模型…

智能优化算法应用:基于秃鹰算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于秃鹰算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于秃鹰算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.秃鹰算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

HTML5+CSS3+Vue小实例:饮料瓶造型文字旋转特效

实例:饮料瓶造型文字旋转特效 技术栈:HTML+CSS+Vue 效果: 源码: 【HTML】【JS】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" …