Spring Boot常用注解深度解析:从入门到精通
今天,这篇文章带你将深入理解Spring Boot中30+常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。
一、启动类与核心注解
1.1 @SpringBootApplication
组合注解:
@SpringBootApplication = @Configuration + @EnableAutoConfiguration +@ComponentScan
@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
三个核心功能:
@Configuration:声明配置类
@EnableAutoConfiguration:启用自动配置
@ComponentScan:组件扫描(默认扫描启动类所在包及其子包)
二、配置与Bean管理
2.1 @Configuration
声明配置类,内部包含多个@Bean方法
@Configuration
public class AppConfig {@Beanpublic DataSource dataSource() {return new HikariDataSource();}
}
2.2 @Bean vs @Component
特性 | @Bean | @Component |
声明位置 | 配置类方法 | 类级别 |
控制粒度 | 第三方库类 | 自己编写的类 |
依赖注入 | 方法参数自动注入 | 字段/构造器 |
2.3 @Scope Bean作用域
@Bean
@Scope("prototype")
public Service prototypeService() {return new Service();
}
三、依赖注入(DI)
3.1 @Autowired
自动注入的三种方式:
// 构造器注入(推荐)
@Autowired
public MyController(MyService service) {this.service = service;
}// Setter注入
@Autowired
public void setService(MyService service) {this.service = service;
}// 字段注入(不推荐)
@Autowired
private MyService service;
3.2 @Qualifier
解决多个同类型Bean的冲突
@Autowired
@Qualifier("mainService")
private Service service;
3.3 @Primary
设置首选Bean
@Bean
@Primary
public Service primaryService() {return new PrimaryService();
}
四、组件扫描与分层架构
4.1 分层注解
@Service
public class UserService {// 业务逻辑
}@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;
}
五、Web开发注解
5.1 请求映射
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {return userService.findById(id);
}@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@RequestBody User user) {return userService.save(user);
}
5.2 参数绑定
@GetMapping
public List<User> searchUsers(@RequestParam(defaultValue = "1") int page,@RequestParam(required = false) String name) {// 分页查询逻辑
}
六、条件装配注解
6.1 @ConditionalOnProperty
@Bean
@ConditionalOnProperty(prefix = "feature",name = "new-payment",havingValue = "true")
public PaymentService newPaymentService() {return new NewPaymentService();
}
6.2 其他条件注解
@ConditionalOnClass:类路径存在指定类时生效
@ConditionalOnMissingBean:容器中不存在指定Bean时生效
七、AOP编程
7.1 切面配置
@Aspect
@Component
public class LoggingAspect {@Pointcut("execution(* com.example.service.*.*(..))")private void serviceLayer() {}@Around("serviceLayer()")public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {// 记录方法执行时间long start = System.currentTimeMillis();Object result = joinPoint.proceed();long duration = System.currentTimeMillis() - start;System.out.println(joinPoint.getSignature() + " executed in " + duration + "ms");return result;}
}
八、配置属性绑定
8.1 @ConfigurationProperties
@Configuration
@ConfigurationProperties(prefix = "app")
public class AppConfig {private String name;private int version;private List<String> servers = new ArrayList<>();// getters/setters
}
application.yml配置:
app:name: MyApplicationversion: 2servers:- server1- server2
九、Bean 的生命周期
Spring Boot 中的 Bean 生命周期是理解 Spring 容器管理 Bean 的关键。Bean 的生命周期大致可以分为以下几个阶段:
实例化(Instantiation):Spring 容器通过调用无参构造方法创建 Bean 实例。
属性赋值(Population):Spring 容器通过反射将配置文件或注解中定义的属性值注入到 Bean 中。
初始化前处理(Pre-initialization):
BeanNameAware:如果 Bean 实现了 BeanNameAware 接口,Spring 会调用其 setBeanName 方法,将 Bean 的名称传递给 Bean。
BeanFactoryAware:如果 Bean 实现了 BeanFactoryAware 接口,Spring 会调用其 setBeanFactory 方法,将 BeanFactory 传递给 Bean。
BeanPostProcessor:Spring 会调用 BeanPostProcessor 的 postProcessBeforeInitialization 方法,对 Bean 进行前置处理。
初始化(Initialization):
InitializingBean:如果 Bean 实现了 InitializingBean 接口,Spring 会调用其 afterPropertiesSet 方法进行初始化。
@PostConstruct:如果 Bean 中有方法使用了 @PostConstruct 注解,Spring 会调用该方法进行初始化。
使用(Usage):Bean 已经初始化完成,可以被应用程序使用。
销毁前处理(Pre-destruction):
DisposableBean:如果 Bean 实现了 DisposableBean 接口,Spring 会调用其 destroy 方法进行销毁前的清理工作。
@PreDestroy:如果 Bean 中有方法使用了 @PreDestroy 注解,Spring 会调用该方法进行销毁前的清理工作。
销毁(Destruction):Spring 容器关闭时,销毁 Bean。
@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {private String name;public MyBean() {System.out.println("1. 实例化 Bean");}@Overridepublic void setBeanName(String name) {System.out.println("2. 设置 Bean 名称");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("3. 设置 BeanFactory");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("4. 初始化 Bean");}@Overridepublic void destroy() throws Exception {System.out.println("6. 销毁 Bean");}@PostConstructpublic void init() {System.out.println("5. @PostConstruct 注解的初始化方法");}@PreDestroypublic void preDestroy() {System.out.println("7. @PreDestroy 注解的销毁前方法");}
}
十、注解关系图谱
总结
Spring Boot 中的注解和 Bean 生命周期是开发中非常重要的概念。通过合理使用各种注解,可以大大简化开发过程,提高开发效率。同时,理解 Bean 的生命周期有助于更好地管理 Bean 的创建、初始化和销毁过程,确保应用程序的稳定性和可靠性。
相关文章:
Spring Boot常用注解深度解析:从入门到精通
今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…...
解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题
mac安装软件时,如果出现这个问题,其实很简单 首先打开终端,输入下面的命令 sudo xattr -r -d com.apple.quarantine 输入完成后,先不要回车,点击访达--应用程序--找到你无法打开的app图标,拖到终端窗口中…...
爱普生L3153打印机无线连接配置流程
家里使用的是移动宽带中兴路由器,有WPS功能,进入192.168.1.1管理员页面,用户名user,密码在路由器背面(可以登录后修改密码)。在网络-WLAN网络配置-WPS中,点击push button,激活路由器…...
第二十章 存储函数
目录 一、概述 二、语法 三、示例 一、概述 前面章节中,我们详细讲解了MySQL中的存储过程,掌握了存储过程之后,学习存储函数则肥仓简单,存储函数其实是一种特殊的存储过程,也就是有返回值的存储过程。存储函数的参数…...
pytorch实现门控循环单元 (GRU)
人工智能例子汇总:AI常见的算法和例子-CSDN博客 特性GRULSTM计算效率更快,参数更少相对较慢,参数更多结构复杂度只有两个门(更新门和重置门)三个门(输入门、遗忘门、输出门)处理长时依赖一般适…...
unity报错不存在类型或者命名空间
导入资源或者打开项目时,突然发现多了一堆报错,如 Assets\2DGamekit\Utilities\DefaultPlayables\ScreenFader\ScreenFaderBehaviour.cs(5,19): error CS0234: The type or namespace name UI does not exist in the namespace UnityEngine (are you mi…...
Qt展厅播放器/多媒体播放器/中控播放器/帧同步播放器/硬解播放器/监控播放器
一、前言说明 音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求&…...
Spring Bean 的生命周期介绍
Spring Bean 的生命周期涉及多个阶段,从实例化到销毁,在开发中我们可以通过各种接口和注解介入这些阶段来定制化自己的功能。以下是详细的生命周期流程: 1. Bean 的实例化(Instantiation) 方式:通过构造函…...
奥卡姆剃刀原理:用简单的力量,解锁复杂的世界
奥卡姆剃刀原理 大名鼎鼎的奥卡姆剃刀原理(Occam’s Razor),其含义很简单,就一句话:“如无必要,勿增实体”。 这句看似简单却蕴含着深刻智慧的话,是由14世纪的英格兰逻辑学家、圣方济各会修士…...
STM32 串口发送与接收
接线图 代码配置 根据上一章发送的代码配置,在GPIO配置的基础上需要再配置PA10引脚做RX接收,引脚模式可以选择浮空输入或者上拉输入,在USART配置串口模式里加上RX模式。 配置中断 //配置中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE…...
如何生成强密码:提高网络安全性的全面指南
引言 在数字化时代,密码的安全性至关重要。随着我们在社交媒体、电子邮件、在线银行等平台上储存越来越多的个人信息,强密码的使用变得更加关键。强密码能有效防止暴力破解、字典攻击等安全威胁。因此,在本文中,我们将深入探讨如…...
如何不更新application.yml而更新spring的配置
更改应用程序外部属性的位置 默认情况下,来自不同来源的属性会按定义的顺序添加到 Spring 中(有关确切顺序,请参阅“Spring Boot 功能”部分中的“外部化配置”)。Environment 您还可以提供以下系统属性(或环境变量&…...
【Unity踩坑】Unity项目管理员权限问题(Unity is running as administrator )
问题描述: 使用Unity Hub打开或新建项目时会有下面的提示。 解决方法: 打开“本地安全策略”: 在Windows搜索栏中输入secpol.msc并回车,或者从“运行”对话框(Win R,然后输入secpol.msc)启…...
【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter1-什么是 JavaScript
一、什么是 JavaScript 虽然 JavaScript 和 ECMAScript(发音为“ek-ma-script”) 基本上是同义词,但 JavaScript 远远不限于 ECMA-262 所定义的那样。没错,完整的 JavaScript 实现包含以下几个部分。 核心(ECMAScript&…...
队列 + 宽搜(4题)
目录 1.n叉树的层序遍历 2.二叉树的锯齿形层序遍历 3.二叉树的最大宽度 4.在每个树行中找最大值 1.n叉树的层序遍历 429. N 叉树的层序遍历 - 力扣(LeetCode) 我们只需要把某个节点出队的时候把它的孩子节点添加进来即可。 出队的次数就是最开始队列…...
二、面向对象
一、结构体类型 结构体类型是一种自定义类型,用于创建我们游戏或者实际业务中的自定义类型. 代码中变量有通用的,可以使用结构体,包裹起来。 1、成员变量 /// <summary> /// 英雄结构体 /// </summary> struct Hero {//成员p…...
【DeepSeek背后的技术】系列二:大模型知识蒸馏(Knowledge Distillation)
目录 1 引言2 操作步骤和公式说明2.1 准备教师模型(Teacher Model)和学生模型(Student Model)2.2 生成软标签(Soft Labels)2.3 定义蒸馏损失函数2.4 训练学生模型2.5 调整超参数2.6 评估与部署 3 其他知识蒸…...
PyQt4学习笔记2】QMainWindow
目录 一、创建 QMainWindow 组件 1. 创建工具栏 2. 创建停靠窗口 3. 设置状态栏 4. 设置中央窗口部件 二、QMainWindow 的主要方法 1. addToolBar() 2. addDockWidget() 3. setStatusBar() 4. setCentralWidget() 5. menuBar() 6. saveState() 和 restoreState() 三、QMainWind…...
《海丰县蔡氏简介》前言
《海丰县蔡氏简介》前言 蔡惠进主编 汕尾市海陆丰蔡姓祖先基本是福建人, 在宋朝时迁至海丰, 因受潮汕文化、 客家文化、 广府文化、 政治归属等系列因素影响, 形成了闽南人一 种新的文化, 既有传统的闽南文化, 又有潮汕…...
深入探索Vue 3组合式API
深入探索Vue 3组合式API 深入探索Vue 3组合式API一、组合式API诞生背景1.1 Options API的局限性1.2 设计目标二、核心概念解析2.1 setup() 函数:组合式API的基石2.2 响应式系统:重新定义数据驱动2.3 生命周期:全新的接入方式2.4 响应式原理探…...
获取 ARM Cortex - M 系列处理器中 PRIMASK 寄存器的值
第一种实现(纯汇编形式) __ASM uint32_t __get_PRIMASK(void) {mrs r0, primaskbx lr }代码分析 __ASM 关键字:这通常是特定编译器(如 ARM GCC 等)用于嵌入汇编代码的指示符。它告诉编译器下面的代码是汇编代码。mrs …...
使用deepseek写一个单击,双击和长按的检测函数
DeepSeek好火,注册试用一下,感觉和chatgpt o1差别不大,唯一的问题就是追多几次就崩溃了,再问不下去了。以下是测试结果。 提问: 请使用c语言写一个函数,输入参数是是为: A为当前的输入量&am…...
MySQL面经
1.范式 第一范式:每一列都不能再拆分 第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不是主键的一部分 第三范式:在第二范式的基础上,非主键列只依赖于主键列,而不依赖于其他非主键…...
【C++】P1765 手机
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯问题描述题目内容示例: 键盘布局 💯我的做法思路问题与优化我的代码实现分析与问题 💯老师的做法思路老师的代码实现分析优点 …...
MyBatis-Plus速成指南:简化你的数据库操作流程
简介: MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatsi-Plus 提供了通用的 Mapper 和 Service,可以不编写任何 SQL 语句的前提下,快速的实现单表的增…...
DeepSeek超越ChatGPT的能力及部分核心原理
DeepSeek超越ChatGPT的能力及部分核心原理 目录 DeepSeek超越ChatGPT的能力及部分核心原理超越ChatGPT的能力核心原理超越ChatGPT的能力 推理计算能力更强:在复杂的数学计算、法律文件审查等任务中,DeepSeek的推理能力可媲美甚至超越部分国际顶尖AI模型,包括ChatGPT。例如在…...
优选算法的灵动之章:双指针专题(一)
个人主页:手握风云 专栏:算法 目录 一、双指针算法思想 二、算法题精讲 2.1. 查找总价格为目标值的两个商品 2.2. 盛最多水的容器 编辑 2.3. 移动零 2.4. 有效的三角形个数 一、双指针算法思想 双指针算法主要用于处理数组、链表等线性数据结构…...
作业day4
请实现一个终端的功能,注意需要带有cd功能 typedef struct sockaddr_in addr_in_t; typedef struct sockaddr addr_t; typedef struct sockaddr_un addr_un_t; char *mygets(char* s,int size){char* res fgets(s,size,stdin);int len strlen(s);if(s[len-1] \n)…...
python日志处理logging
python日志处理logging 在项目开发中,日志信息是程序中必不可少的组成部分。每一种语言都有相应的日志模块,如java中log4j,而python中是通过logging模块来提供日志功能。 日志要哪些本质功能? 在分享日志logging模块之前&#…...
开发板目录 /usr/lib/fonts/ 中的字体文件 msyh.ttc 的介绍【微软雅黑(Microsoft YaHei)】
本文是博文 https://blog.csdn.net/wenhao_ir/article/details/145433648 的延伸扩展。 本文是博文 https://blog.csdn.net/wenhao_ir/article/details/145433648 的延伸扩展。 问:运行 ls /usr/lib/fonts/ 发现有一个名叫 msyh.ttc 的字体文件,能介绍…...
浅谈《图解HTTP》
感悟 滑至尾页的那一刻,内心突兀的涌来一阵畅快的感觉。如果说从前对互联网只是懵懵懂懂,但此刻却觉得她是如此清晰而可爱的呈现在哪里。 介绍中说,《图解HTTP》适合作为第一本网络协议书。确实,它就像一座桥梁,连接…...
为什么在网站上复制的图片不能直接粘贴到本地的原因及解决方法
一、图片的来源与格式 ①图片链接:许多网站展示的图片并不是直接嵌入在页面中的,而是通过URL链接到远程服务器上的图片。当你复制网站上的图片时,实际上复制的是图片的URL地址,而不是图片的本地文件。 ②动态加载:有些网站使用JavaScript或其他技术动态加载图片,可能通…...
conda配置channel
你收到 CondaKeyError: channels: value https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main not present in config 错误是因为该镜像源(https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main)可能没有被正确添加到 Conda 的配置文件中&…...
Javaweb学习之Mysql(Day5)
(一)Mysql概述 (1)MYSQL通用语法 SQL语句可以单行或多行书写,以分号结尾。 SQL语句可以使用空格/缩进来增强语句的可读性(即,空格和缩进不影响代码的执行)。 MySQL数据库的SQL语句不区分大小写。 注释: 1. 单行注释: -- 注释内容 或 # 注释内容 (MySQL 特有 …...
61.异步编程1 C#例子 WPF例子
和普通的任务绑定不太相同的部分如下: public MainWindowViewModel(){FetchUserInfoCommand new RelayCommand(async (param) > await FetchUserInfoAsync());}private async Task FetchUserInfoAsync(){// 模拟异步操作,比如网络请求await Task.Del…...
自定义数据集 使用scikit-learn中svm的包实现svm分类
引入必要的库 import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.metrics import accuracy_score, classification_report 生成自定义数据集 X, y ma…...
Qt跨屏窗口的一个Bug及解决方案
如果我们希望一个窗口覆盖用户的整个桌面,此时就要考虑用户有多个屏幕的场景(此窗口要横跨多个屏幕),由于每个屏幕的分辨率和缩放比例可能是不同的,Qt底层在为此窗口设置缩放比例(DevicePixelRatio…...
Python零基础快速入门课程,自带在线运行环境
Python零基础入门教程 编译器地址: Python在线编译器 课程目录: Python简介 Python是一种简单易学、功能强大的编程语言。它具有高效的数据结构,能够简单有效地实现面向对象编程。 Python的优点: 简单易学,所有人都可以零基础入门开源免费,有丰富的免费学习课程跨平台…...
Java 数据库连接池:HikariCP 与 Druid 的对比
Java 数据库连接池:HikariCP 与 Druid 的对比 数据库连接池:HikariCP 1. 卓越的性能表现 HikariCP 在数据库连接池领域以其卓越的性能脱颖而出。 其字节码经过精心优化,减少了不必要的开销,使得连接获取和释放的速度极快。 在…...
51单片机 04 编程
一、模块化编程 .c文件:函数、变量的定义 .h文件:可被外部调用的函数、变量的声明 函数在调用前必须有定义或者声明。 预编译:以#开头,作用是在真正的编译开始之前,对代码做一些处理(预编译)…...
基于Springboot框架的学术期刊遴选服务-项目演示
项目介绍 本课程演示的是一款 基于Javaweb的水果超市管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该项目附…...
Vite:现代前端开发的利器
Vite:现代前端开发的利器 随着前端技术的快速发展,开发工具也在不断迭代和优化。Vite 是近年来备受关注的一款前端构建工具,它以极快的冷启动速度和高效的开发体验赢得了开发者的青睐。本文将详细介绍 Vite 的特点、工作原理以及它为何成为现…...
[蓝桥杯 2024 省 B] 好数
[蓝桥杯 2024 省 B] 好数 题目描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 …...
基于Flask的全国星巴克门店可视化分析系统的设计与实现
【FLask】基于Flask的全国星巴克门店可视化分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言,结合Flask框架进行后端开发&…...
2502,索界面3
原文 SonicUI,你从未见过的方便GUI引擎-源码 介绍 SonicUI是基于原生GDIAPI的GUI引擎.它提供了几个简单的UI组件来实现高效的UI效果,如自绘按钮,不规则窗口,动画,窗口中的网径和图像操作方法. 主要目的是用最少的代码来达到最佳效果. 背景 周知,UI开发一般重复用无趣.因此…...
基础笔记|splice()的用法
一、三种用法 splice(index, 0, element) 插入 元素,不删除任何元素。splice(index, deleteCount) 删除 deleteCount 个元素。splice(index, deleteCount, element1, element2, ...) 替换 元素,即删除 deleteCount 个元素,同时插入新的元素。…...
电商项目高级篇09-检索服务
电商项目高级篇09-检索服务 1、环境搭建1.1、前端静态文件准备1.2、search服务引入模版引擎1.3、index.html页面复制到templates文件夹下1.4、模仿product项目,引入名称空间1.5、动静分离,静态资源路径位置替换1.6、将1.1的静态资源放到nginx目录下1.7、…...
如何使用 DeepSeek 和 Dexscreener 构建免费的 AI 加密交易机器人?
我使用DeepSeek AI和Dexscreener API构建的一个简单的 AI 加密交易机器人实现了这一目标。在本文中,我将逐步指导您如何构建像我一样的机器人。 DeepSeek 最近发布了R1,这是一种先进的 AI 模型。您可以将其视为 ChatGPT 的免费开源版本,但增加…...
Meta财报解读:营收超预期,用户增长放缓,AI与元宇宙仍是烧钱重点
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
2024美团秋招硬件开发笔试真题及答案解析
目录 一、单选题 1、C语言中变量有一系列的命名规则,下列选项中,属于错误的C语言变量命名规则的是() 2、以下 C 代码的运行结果是什么() 3、执行下面程序,正确的输出是() 4、以下不正确的定义语句是() 5、执行语句for (i = 2; i++ < 7;);后, i 的值变为()…...