SpringBoot 基础(Spring)

SpringBoot 基础(Spring)

Bean 注解标记和扫描 (IoC)


配置类概念

  • @SpringBootConfiguration 或者 @Configuration 注解标注的类就是配置类
  • 配置类本身也会加入 IoC 容器*
@Configuration
public class configuration1 {}@SpringBootConfiguration
public class configuration1 {}

标记 Bean

Spring 提供多种注解用于定义 Bean:

  • @Component:通用注解,标记类为 Spring Bean,可用于各层,如 Service、Dao 等,直接标注在类上即可。
  • @Repository:专用于 Dao 层类,
  • @Service:用于 Service 层类,
  • @Controller:用于 Controller
    .

注意: 源码显示,@Controller、@Service、@Repository 基于 @Component 起名,对 Spring IOC 管理无实质区别,仅为方便开发者区分组件作用。虽本质相同,但为保证代码可读性与结构严谨性,不可随意标注。

@Component
public class CommonComponent {}@Controller
public class XxxController {}@Repository
public class XxxDao {}@Service
public class XxxService {}

扫描 Bean

SpringBoot 主程序的 @SpringBootApplication 会自动扫描 Bean

SpringBootAplication 整合了以下注解

  • @SpringBootConfiguration —— 表示这个类本身是个配置类
  • @EnableAutoConfiguration —— 自动加载其他的配置类
  • @ComponentScan 默认是扫描当前类所在的包和子包
    • 自定义一个 @ComponentScan(basePackages = "包1", "包2")
    • 或者 @SpringBootApplication(scanBasePackages = "包1", "包2")
//@SpringBootConfiguration //表示这个类本身是个配置类
//@EnableAutoConfiguration //自动加载其他的配置类
//@ComponentScan //默认是扫描当前类所在的包和子包
@SpringBootApplication
public class Boot302DemoApplication {public static void main(String[] args) {var ioc = SpringApplication.run(Boot302DemoApplication.class, args);}}

第三方组件加入 IoC 容器

第一种方法:@Bean

第三方 jar 我们不可能直接在源码加 @Component 所以需要用 @Bean 标签

  • @Bean:方法返回值作为 Bean 类型:在使用 @Bean注解 的方法中,方法的返回值类型决定了 Bean 的类型。
  • 例如,如果方法返回一个DataSource 类型的对象,那么这个 BeanSpring 容器中的类型就是 DataSource。这个类型可以是 具体的类,也可以是 接口 或者 抽象类

.
注意:@Bean 只能在配置类里面写。当然不仅是第三方 jar 普通的也行

@Configuration
public class AppConfig {//@Beanpublic FastsalException fastsalException() {return new FastsqlException();}
}
第二种方式:@Import

快速把类放入 IoC 容器 (第三方或者自己的类都可以)。常用于整合配置类等操作。

  • 配置类放进 IoC 容器相比与配置类配置的所有组件都会放进 IoC 容器

  • 也只能在配置类中使用

@Configuration
@Import(FastsalException.class) //快速把第三方地 FastsalException类放入 IoC 容器
public class AppConfig {}

BeanBeanName 问题

@ComponentBeanName

  • 默认情况:和首字母小写的类名相同。 例如:SoldierController 类对应的 bean 的 id 就是 soldierController
  • 自己指定:@Controller( value = "BeanName")

@BeanBeanName

  • 默认情况:和方法名相同
  • 自己指定:@Bean("BeanName")

Bean 的初始化和销毁方法

我们可以在组件类中定义方法,然后当 IoC 容器 实例化和销毁组件 对象的时候进行自动调用!这两个方法我们称为为生命周期方法!
.
类似于Servlet的 init/destroy 方法, 我们可以在周期方法完成初始化和释放资源等工作。

第一种:直接声明

//只要有 Bean 初始化和销毁了就执行这里的两个方法
public class BeanOne {//周期方法要求: 方法命名随意,但是要求方法必须是 public void 无形参列表@PostConstruct  //注解制指定初始化方法public void init() {// 初始化逻辑}@PreDestroy //注解指定销毁方法public void cleanup() {// 释放资源逻辑}}

第二种:通过 @Bean 指定

public class BeanOne {public void init() {// initialization logic}
}public class BeanTwo {public void cleanup() {// destruction logic}
}@Configuration
public class AppConfig {@Bean(initMethod = "init")public BeanOne beanOne() {return new BeanOne();}@Bean(destroyMethod = "cleanup")public BeanTwo beanTwo() {return new BeanTwo();}
}

Bean 的单例和多例问题

取值含义创建对象的时机默认值
singleton在 IOC 容器中,这个 bean 的对象始终为单实例IOC 容器初始化时
prototype这个 bean 在 IOC 容器中有多个实例获取 bean 时

第一种方式:全名声明

//ConfigurableBeanFactory.SCOPE_PROTOTYPE 就是多例
//单例模式就是只要实例化一个 bean 就执行一次
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 单例
@Component
public class JavaBean {}

第二种方式:简洁声明

@Scope("prototype") // 单例
@Component
public class JavaBean {}

两者区别

  • @Scope("prototype")
    • 对于初学者或简单项目,使用字符串的方式可能更容易理解和书写,但是在大型项目中,如果作用域名称拼写错误(例如写成 “prototyp”),编译器不会给出错误提示,可能导致运行时问题。
  • @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    • 使用 ConfigurableBeanFactory.SCOPE_PROTOTYPE 常量可以避免拼写错误,因为 IDE 会在编译时检查该常量是否存在,同时也更符合 Java 编程的最佳实践,即使用常量而不是硬编码字符串。

Bean 依赖注入:引用类型自动装配(DI)


前提条件:参与自动装配的组件,无论是要被装配的还是提供装配的,都必须在 IoC 容器里,并且 IoC 容器的实现方式(XML 配置或者注解方式)对此没有影响。

@Autowired:按照类型装配

  • @Autowired 注解使用方法:可以直接在成员变量上标记 @Autowired 注解 来自动注入对象,在实际项目中我们通常采用这种方式。甚至第三方类放入容器后,也能使用此注解来实现自动装配。

  • 原理

    • 在 ioc 容器中查找符合类型的组件对象
    • 设置给当前属性(di)
  • @Autowired 标记的位置:成员变量,get方法, 构造器

  • Bean
@Repository
public class UserDao {}@Service
public class UserService {private UserDao userDao;public UserDao getUserDao() {return userDao;}
}
  • @Autowired 注入
@Service
public class UserService {//这里相当于注入了 UserDao 类型的对象@Autowiredprivate UserDao userDao;public UserDao getUserDao() {return userDao;}
}

@Autowired 装配流程
·
在这里插入图片描述

@Qualifier:指定 BeanName 装配

根据 @Qualifier 注解中指定的名称作为 BeanName 进行匹配。需要配合 @Autowired

@Repository
public class UserDao {private UserDao userDao;//匹配 BeanName 为 userDao 进行装配//value 可以省略@Autowired@Qualifier(value = "userDao")public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

@Resource:多功能装配

  • 如果没有指定 name, 先根据 属性名 查找 IoC 中组件
  • 如果没有指定 name, 并且属性名没有对应的组件, 会根据 属性类型 查找
  • 如果指定name名称查找。Resource(name='test') == @Autowired + @Qualifier(value='test')
Repository
public class UserDao {@Resource(name = "userDao")private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

@Bean 声明组件之间的装配

第一种方式:直接调用方法

如果其他组件也是 @Bean 方法 也可以 直接的调用方法这个本质上从 IoC 容器获取组件

  • POJO
public class Money {}public class People {private Money money;public void setMoney(Money money) {this.money = money;}
}
  • 配置类
@SpringBootConfiguration
public class configuration1 {@Beanpublic Money money() {return new Money();}@Beanpublic People people() {People people = new People();//直接调用方法本质上从 ioc 容器获取组件people.setMoney(money());return people;}}
第二种方式:形参列表自动注入

形参列表声明自动注入

  • 要求必须有对应的类型的组件, 如果没有抛异常
  • 如果有多个同类型的 Bean 。可以使用 形参名称 = 对应的 beanName 的方式
  • POJO
public class Money {}public class People {private Money money;public void setMoney(Money money) {this.money = money;}
}
  • 配置类
@SpringBootConfiguration
public class configuration1 {@Bean //默认方法名就是BeanNamepublic Money money() {return new Money();}@Beanpublic People people(Money money) {People people = new People();people.setMoney(money);return people;}}

Bean 依赖注入:基本类型装配(DI)


第一种方式:@Value 直接绑定

  • @Value 是 Spring 框架中的一个注解,其主要作用是将外部配置文件中的具体值注入到由 Spring 管理的组件的字段中。这里所说的 Spring 管理的组件,通常是指带有 @Component 注解的类。
  • 具体使用时,在字段上添加 @Value("${某个属性名}") 注解。当 Spring 应用启动时,它会自动从配置文件里查找与注解中指定属性名相对应的值,并将该值填充到使用 @Value 注解标注的字段中。
    .

使用

  • 情况1:${key} 取外部配置 key 对应的值!
  • 情况2:${key : defaultValue} 没有 key, 可以给与默认值
  • properties 配置文件
username=mangfu
gender=男
age=20
  • 开始注入
@Component
//导入 properties配置文件
@Data
public class MyComponent {//注入@Value("${username}")private String name;@Value("${age}")private String age;@Value("${gender}")private String gender;}

第二种方式:@configurationProperteis 根据前缀绑定

@ConfigurationProperties

前提是要用 @Component 或者 @Bean 把类加入 IoC 容器。并且有 get set 方法

  • application.properties
pig.id=1
pig.name=佩奇
pig.age=5
  • @Component 方式
@Data
//必须加入 IoC 容器 @ConfigurationProperties(prefix = "pig") 才生效
@Component
//根据前缀为 pig 的自动匹配和 properties 一样的后缀然后赋值
@ConfigurationProperties(prefix = "pig")
public class Sheep {private Long id;private String name;private Integer age;}
  • @Bean 方式
@Configuration
public class AppConfig2 {@ConfigurationProperties(prefix = "pig")@Beanpublic Pig pig() {return new Pig();}
}
@EnableConfigurationProperties

Spring Boot 默认只扫描主程序所在包,导入第三方包时,即便组件标有 @Component@ConfigurationProperties,也因扫描不到而无法完成属性绑定和注册到容器。
.

使用 @EnableConfigurationProperties(Sheep.class) 可快速对指定类(如 Sheep 类)进行属性绑定并注册到容器。
,
使用该注解需注意:

  • 先使用 @ConfigurationProperties(prefix = " ") 绑定指定类。
  • 在配置类中使用。
  • Application.properties
sheep.id=1
sheep.name=苏西
sheep.age=5
  • POJO
//可以不用 @Component 加入 IoC 容器。等下 @EnableConfigurationProperties 会把它加入 IoC并赋值 
@ConfigurationProperties(prefix = "sheep")
public class Sheep {private Long id;private String name;private Integer age;}
  • 配置类
//这里就把 Sheep 加入 IoC 容器并且对应赋值了
@EnableConfigurationProperties(Sheep.class)
public class AppConfig2 {}

@ConditionalOnXXX 条件判断注解


如果注解指定的条件成立,则触发指定行为

  • @ConditionalOnClass:如果类路径中存在这个类,则触发指定行为

  • @ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为

  • @ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为

  • @ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为

  • @ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值

.
如果是类级别就。类里所有操作都执行或不执行

举例

@SpringBootConfiguration
public class AppConfig {//类路径中存在这个类就创建这个 Bean 			 @ConditionalOnClass(name="com.atguigu.boot.controller.HelloController.class")@Beanpublic Money money() {return new Money();}//类路径中不存在这个类就创建这个 Bean 	@ConditionalOnMissingClass(value ="com.atguigu.boot.controller.HelloController.class")@Beanpublic People person() {return new People();}
}

SpringBoot 获取 Bean


之前我们用的是 AnnotationConfigApplicationContext。现在 主程序SpringApplication.run 返回的是 ConfigurableApplicationContextConfigurableApplicationContext接口类型
.

AnnotationConfigApplicationContextConfigurableApplicationContextConfigurableApplicationContext 的具体实现类。所以相当于直接创建好了 ApplicationContext 了我们直接获取 IoC 中的容器就行

第一种方式:根据 BeanName 获取

直接根据 beanName 获取即可 返回值类型是 Object 需要强转 【不推荐】

Object happyConponent = applicationContext.getBean("happyComponent");

第二种方式:根据 BeanName 同时定制 Class

HappyComponent happyComponent1 = applicationContext.getBean("happyComponent", HappyComponent.class);

第三种方式:直接根据类型获取

直接根据类型获取

  • 条件1:同一个类型, 在 Ioc 容器中只能有一个 Bean,如果 IoC 容器中存在多个同类型的 Bean 会出现: NoUniqueBeanFinitionException
  • 条件2IoC 的配置一定是实现类, 但是可以通过接口类型获取触发多态
    .

原理:根据类型来获取 Bean 时,在满足 Bean 唯一性的前提下,其实只是看:【对象 instanceof 指定的类型】的返回结果,只要返回的是 true 就可以认定为和类型匹配,能够获取到。

//A 是接口 HappyComponent 是实现类
A bean = applicationContext.getBean(A.class);
bean.doWork();

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

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

相关文章

【数据结构与算法】九大排序算法实现详解

文章目录 Ⅰ. 排序的概念及其运用一、排序的概念二、常见的排序算法三、排序算法的接口四、测试算法接口附:Swap接口(使用异或的方法实现) Ⅱ. 排序算法的实现一、插入排序二、希尔排序( 缩小增量排序 )三、选择排序四、堆排序五、冒泡排序六…

Ansys Maxwell:采用对称性的双转子轴向磁通电机

轴向磁通电机因其功率密度高于相同重量的传统径向磁通电机而变得非常受欢迎,并且在电动汽车和航空应用中非常高效且具有成本效益。功率密度是输出功率与机器体积的比率。对于给定尺寸的机器,轴向磁通电机提供更大的扭矩和功率,或者对于给定的…

Leetcode:219

1&#xff0c;题目 2&#xff0c;思路 第一种就是简单的暴力比对当时过年没细想 第二种&#xff1a; 用Map的特性key唯一&#xff0c;把数组的值作为Map的key值我们每加载一个元素都会去判断这个元素在Map里面存在与否如果存在进行第二个判断条件abs(i-j)<k,条件 符合直接…

Hugging Face挑战DeepSeek,AI开源竞赛升级!

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南

1.27 线性代数王国&#xff1a;矩阵分解实战指南 #mermaid-svg-JWrp2JAP9qkdS2A7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JWrp2JAP9qkdS2A7 .error-icon{fill:#552222;}#mermaid-svg-JWrp2JAP9qkdS2A7 .erro…

巴塞尔问题详解:计算所有正整数平方的倒数之和

1 相关历史背景 巴塞尔问题&#xff08;Basel Problem&#xff09;是数学史上一个著名的问题&#xff0c;由意大利数学家皮埃特罗门戈利&#xff08;Pietro Mengoli&#xff09;在1644年首次提出。 但他未能解决&#xff0c;只能给出小数点后六位的近似解是1.644934&#xff0…

android 圆形弹窗摄像头开发踩坑——源码————未来之窗跨平台操作

一、飘窗刷脸&#xff0c;拍照采用飘窗 刷脸认证安卓接口采用飘窗具有在不干扰用户主要操作的前提下以醒目方式引导用户完成认证&#xff0c;且能灵活定制样式以提升用户体验和认证效率的优点 二、踩坑只有一个扇形 <?xml version"1.0" encoding"utf-8&quo…

电子电气架构 --- 在智能座舱基础上定义人机交互

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

图漾相机——Sample_V1示例程序

文章目录 1.SDK支持的平台类型1.1 Windows 平台1.2 Linux平台 2.SDK基本知识2.1 SDK目录结构2.2 设备组件简介2.3 设备组件属性2.4 设备的帧数据管理机制2.5 SDK中的坐标系变换 3.Sample_V1示例程序3.1 DeviceStorage3.2 DumpCalibInfo3.3 NetStatistic3.4 SimpleView_SaveLoad…

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径&#xff0c;在idea的plugins下面的lib文件夹内&#xff1a;java-decompiler.jar。下面是我自己本地的插件路径&#xff0c;以作参考&#xff1a; D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…

1.五子棋对弈python解法——2024年省赛蓝桥杯真题

问题描述 原题传送门&#xff1a;1.五子棋对弈 - 蓝桥云课 "在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f;" 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着"友谊第…

基于STM32的智能停车场管理系统设计

目录 引言系统设计 硬件设计软件设计 系统功能模块 车辆识别与进出管理模块车位检测与引导模块计费与支付模块数据存储与查询模块远程监控与异常报警模块 控制算法 车牌识别与车辆进出管理算法车位检测与引导算法计费与支付处理算法数据存储与远程反馈算法 代码实现 车辆检测与…

单细胞-第五节 多样本数据分析,打分R包AUCell

文件在单细胞\5_GC_py\1_single_cell\3.AUCell.Rmd 1.基因 rm(list = ls()) load("g.Rdata")2.AUCell https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9897923 IF: NA NA NA用这个文章里的方法,将单细胞亚群的marker基因与ros相关基因取交集,用作AUCell的基因集…

蓝牙技术在物联网中的应用有哪些

蓝牙技术凭借低功耗、低成本和易于部署的特性&#xff0c;在物联网领域广泛应用&#xff0c;推动了智能家居、工业、医疗、农业等多领域发展。 智能家居&#xff1a;在智能家居系统里&#xff0c;蓝牙技术连接各类设备&#xff0c;像智能门锁、智能灯泡、智能插座、智能窗帘等。…

NLP深度学习 DAY5:Seq2Seq 模型详解

Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;模型是一种用于处理输入和输出均为序列任务的深度学习模型。它最初被设计用于机器翻译&#xff0c;但后来广泛应用于其他任务&#xff0c;如文本摘要、对话系统、语音识别、问答系统等。 核心思想 Seq2Seq 模型的目标是将…

单细胞-第四节 多样本数据分析,下游画图

文件在单细胞\5_GC_py\1_single_cell\2_plots.Rmd 1.细胞数量条形图 rm(list ls()) library(Seurat) load("seu.obj.Rdata")dat as.data.frame(table(Idents(seu.obj))) dat$label paste(dat$Var1,dat$Freq,sep ":") head(dat) library(ggplot2) lib…

NLP模型大对比:Transformer >Seq2Seq > LSTM > RNN > n-gram

结论 Transformer 大于 传统的Seq2Seq 大于 LSTM 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异&#xff1a; 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的&q…

Julius AI 人工智能数据分析工具介绍

Julius AI 是一款由 Casera Labs 开发的人工智能数据分析工具&#xff0c;旨在通过自然语言交互和强大的算法能力&#xff0c;帮助用户快速分析和可视化复杂数据。这款工具特别适合没有数据科学背景的用户&#xff0c;使数据分析变得简单高效。 核心功能 自然语言交互&#x…

H3CNE-31-BFD

Bidirectional Forwarding Dection&#xff0c;双向转发检查 作用&#xff1a;毫秒级故障检查&#xff0c;通常结合三层协议&#xff08;静态路由、vrrp、ospf、BGP等&#xff09;&#xff0c;实现链路故障快速检查。 BFD配置示例 没有中间的SW&#xff0c;接口down&#xff…

2025最新版MySQL安装使用指南

2025最新版MySQL安装使用指南 The Installation and Usage Guide of the Latest Version of Oracle MySQL in 2025 By JacksonML 1. 获取MySQL 打开Chrome浏览器&#xff0c;访问官网链接&#xff1a;https://www.mysql.com/ &#xff0c;随即打开MySQL官网主页面&#xff…