深入 Spring Boot 注解
深入 Spring Boot 注解:我的开发心得与常用注解详解
大家好,我是 [你的 CSDN 昵称/名字],一位热爱 Spring Boot 的技术博主。 在多年的 Spring Boot 开发实践中,我深深体会到注解的强大魅力。它们不仅让代码变得更简洁,更重要的是,它们极大地提升了我们的开发效率和代码的可读性。
今天,我想跟大家分享一些我在 Spring Boot 开发中 最常用、也觉得最有价值的注解,希望能帮助大家更好地理解和应用 Spring Boot 注解,让你的 Spring Boot 开发之路更加顺畅。
1. 注解,我的 Spring Boot 开发利器
说实话,刚开始接触 Spring Boot 的时候,我也被各种注解搞得有点晕。 但一旦理解了它们的精髓,你会发现,注解就像是 Spring Boot 赐予我们的魔法棒,挥一挥就能实现很多复杂的功能,而且代码还特别优雅!
我个人认为,注解是 Spring Boot 的灵魂之一。 它体现了 Spring Boot “约定优于配置” 的核心思想,让我们能够专注于业务逻辑,而不用花费大量时间在繁琐的 XML 配置上。
在接下来的内容中,我会结合我自己的开发经验,由浅入深地介绍 Spring Boot 中那些 真正能帮到你 的常用注解。
2. Bean 管理注解:构建应用的基石
这些注解是我每天都在用的,它们就像 Spring Boot 应用的骨架,负责 Bean 的定义、依赖注入,让我们的应用结构清晰、易于维护。
2.1 组件扫描与 Bean 定义:让 Spring Boot 自动发现你的 Bean
-
@Component: 这是 Bean 定义的基石! 只要你希望 Spring Boot 管理一个类,把它变成 Bean,就毫不犹豫地用@Component注解它。 Spring Boot 启动时会自动扫描并注册这些组件。@Component // 标记 MyComponent 为 Spring 组件 public class MyComponent {public void doSomething() {System.out.println("MyComponent 正在工作!");} } -
@Service: 我习惯用@Service来标记业务逻辑层的类,比如UserService、OrderService等。 它其实也是@Component,但语义上更清晰,一看就知道这是个服务组件。@Service // 标记 UserService 为服务组件 public class UserService {// ... 业务逻辑 ... } -
@Repository: 数据访问层的类,比如UserRepository、OrderRepository,我都会用@Repository注解。 它也是@Component的特化,而且通常还带有 异常转换 的功能,让数据访问层的异常处理更规范。@Repository // 标记 UserRepository 为数据仓库组件 public class UserRepository {// ... 数据访问操作 ... } -
@Controller&@RestController: 这两个是 Web 开发必备!@Controller用于传统的 MVC 控制器,@RestController则用于构建 RESTful API,返回 JSON 或 XML 数据。 我个人更喜欢用@RestController,简洁高效。@RestController // RESTful 控制器,返回值直接作为响应体 public class MyRestController {@GetMapping("/hello")public String hello() {return "你好,REST!";} } -
@Configuration&@Bean: 如果你想手动配置一些 Bean,或者从第三方库创建 Bean,@Configuration和@Bean就派上用场了。@Configuration标记配置类,@Bean标记配置方法,返回的对象会被注册为 Bean。@Configuration // 标记 AppConfig 为配置类 public class AppConfig {@Bean // 将 message 方法的返回值注册为 Beanpublic String message() {return "你好,Bean!";} }
2.2 依赖注入:让 Spring Boot 帮你管理 Bean 之间的关系
-
@Autowired: 依赖注入的核心注解! 只要你想让 Spring Boot 自动帮你注入 Bean,就用@Autowired注解字段、构造器或者方法参数。 Spring Boot 会自动找到匹配的 Bean 并注入进来,简直不要太方便!@Service public class MyService {@Autowired // 自动注入 UserRepository Beanprivate UserRepository userRepository;// ... 使用 userRepository ... } -
@Qualifier: 有时候,同一个接口可能会有多个实现类,这时候@Autowired就不知道该注入哪个了。@Qualifier可以帮我们指定要注入哪个具体的 Bean,通过 Bean 的名称来区分。@Service public class MyService {@Autowired@Qualifier("specialUserRepository") // 指定注入名为 "specialUserRepository" 的 Beanprivate UserRepository userRepository; } -
@Value: 读取配置文件 (例如application.properties或application.yml) 中的属性值,用@Value就搞定了。 非常方便读取各种配置信息。@Service public class MyService {@Value("${my.app.name}") // 注入 application.properties 中的 myapp.name 属性值private String appName;// ... 使用 appName ... }
3. Web 开发注解:轻松构建 Web 应用
这些注解是我构建 Web 应用的得力助手,它们让请求处理、参数绑定、响应构建都变得非常简单。
3.1 请求映射:URL 路由的利器
-
@RequestMapping: 最强大的请求映射注解,可以用于类级别和方法级别。 可以指定请求方法、路径、参数等等,非常灵活。@RestController @RequestMapping("/api") // 类级别映射:所有 /api 开头的请求 public class ApiController {@RequestMapping(value = "/users", method = RequestMethod.GET) // 方法级别映射:/api/users GET 请求public List<User> getUsers() {// ... 返回用户列表 ...} } -
@GetMapping,@PostMapping, …:@RequestMapping的快捷方式,更简洁直观。 我更倾向于使用这些快捷注解,代码更清爽。@RestController @RequestMapping("/api") public class ApiController {@GetMapping("/users") // 相当于 @RequestMapping(value = "/users", method = RequestMethod.GET)public List<User> getUsers() {// ... 返回用户列表 ...}@PostMapping("/users") // 相当于 @RequestMapping(value = "/users", method = RequestMethod.POST)public ResponseEntity<User> createUser(@RequestBody User user) {// ... 创建用户 ...return ResponseEntity.status(HttpStatus.CREATED).body(user);} }
3.2 请求参数绑定:轻松获取请求数据
-
@PathVariable: 从 URL 路径中提取参数,例如/users/{id}中的{id}。 我经常用它来获取资源 ID。@RestController @RequestMapping("/api") public class ApiController {@GetMapping("/users/{id}") // URL 路径中的 {id} 变量public ResponseEntity<User> getUserById(@PathVariable Long id) { // 绑定到 id 参数// ... 根据 id 获取用户 ...return ResponseEntity.ok(user);} } -
@RequestParam: 获取请求参数 (Query Parameters),例如/search?keyword=spring&page=1中的keyword和page。 用于处理搜索、分页等场景非常方便。@RestController @RequestMapping("/api") public class ApiController {@GetMapping("/search") // 例如:/api/search?keyword=spring&page=1public List<User> searchUsers(@RequestParam String keyword, // 绑定 "keyword" 参数@RequestParam(defaultValue = "1") int page) { // 绑定 "page" 参数,并设置默认值// ... 根据 keyword 和 page 搜索用户 ...return searchResult;} } -
@RequestBody: 接收请求体 (Request Body) 中的数据,例如 POST 或 PUT 请求提交的 JSON 数据。 构建 RESTful API 时,这个注解非常常用。@RestController @RequestMapping("/api") public class ApiController {@PostMapping("/users")public ResponseEntity<User> createUser(@RequestBody User user) { // 将请求体 JSON 数据绑定到 User 对象// ... 创建用户 ...return ResponseEntity.status(HttpStatus.CREATED).body(user);} }
3.3 响应处理:快速返回数据
-
@ResponseBody: 让方法返回值直接作为响应体返回,而不是跳转到视图。 构建 RESTful API 时,通常会配合@RestController使用,或者在@Controller方法上使用@ResponseBody。@Controller @RequestMapping("/api") public class ApiController {@GetMapping("/message")@ResponseBody // 返回值 "Hello, ResponseBody!" 直接作为响应体public String getMessage() {return "Hello, ResponseBody!";} }
4. 数据访问注解:简化数据库操作
如果你跟我一样,经常和数据库打交道,那么 Spring Data JPA 绝对是你的福音! 而这些 JPA 和 Spring Data JPA 注解,就是我们操作数据库的强大武器。
4.1 JPA 实体注解:定义你的数据模型
-
@Entity&@Table:@Entity标记一个类为 JPA 实体类,@Table指定数据库表名。 有了这两个注解,你的 Java 类就和数据库表关联起来了。@Entity // 标记 User 类为 JPA 实体类 @Table(name = "users") // 指定数据库表名为 "users" public class User {// ... 属性 ... } -
@Id&@GeneratedValue: 定义实体类的主键。@Id标记主键字段,@GeneratedValue指定主键生成策略,例如自增长。@Entity public class User {@Id // 标记 id 字段为主键@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增长private Long id;// ... 其他属性 ... } -
@Column: 配置实体类属性和数据库列的映射关系,例如列名、长度、是否非空等等。@Entity public class User {@Id// ...@Column(name = "user_name", nullable = false, length = 50) // 指定列名、非空、长度private String userName;// ... 其他属性 ... } -
关系映射注解 (例如
@ManyToOne,@OneToMany, …): 定义实体类之间的关联关系,例如用户和订单的一对多关系,用关系映射注解就能轻松实现。
4.2 Spring Data JPA 注解:让数据访问更简单
-
@Repository(Spring Data JPA): 标记一个接口为 Spring Data JPA Repository。 神奇的地方来了! 只要你继承JpaRepository,Spring Data JPA 就会自动帮你生成常用的 CRUD 操作方法,比如save()、findById()、findAll()等等,简直不要太省事!@Repository // 标记 UserRepository 为 Spring Data JPA Repository public interface UserRepository extends JpaRepository<User, Long> { // 继承 JpaRepositoryList<User> findByUserName(String userName); // Spring Data JPA 方法名约定查询 } -
@Transactional: 事务管理注解。 保证一组数据库操作的 原子性,要么全部成功,要么全部失败回滚。 用@Transactional注解方法或类,Spring Boot 就会自动帮你处理事务。@Service @Transactional // 类级别事务:UserService 中所有方法都具有事务特性 public class UserService {@Autowiredprivate UserRepository userRepository;@Transactional(readOnly = true) // 方法级别事务,并设置为只读事务public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}public void createUser(User user) { // 具有类级别的事务特性userRepository.save(user);} }
5. 配置管理注解:灵活管理应用配置
-
@ConfigurationProperties: 批量读取配置文件中的属性值,并绑定到 Java Bean。 让配置管理更结构化、更方便。@ConfigurationProperties(prefix = "myapp") // 属性前缀为 "myapp" @Component public class MyAppProperties {private String name;private String version;// ... getter 和 setter ... }// 在 application.properties 或 application.yml 中配置: // myapp.name=My Spring Boot App // myapp.version=1.0.0 -
@PropertySource: 加载额外的属性文件。 默认 Spring Boot 会加载application.properties和application.yml, 如果你还有自定义的属性文件,可以用@PropertySource加载进来。@Configuration @PropertySource("classpath:my-config.properties") // 加载 classpath 下的 my-config.properties 文件 public class MyConfig {@Value("${my.custom.property}")private String customProperty;// ... }
6. 我的总结与开发建议
总结一下,这篇文章主要介绍了我在 Spring Boot 开发中最常用的一些注解。 当然,Spring Boot 的注解远不止这些,还有很多强大的注解等待我们去探索。
我的建议是:
- 先掌握最常用的注解: 例如
@Component,@Service,@Autowired,@RestController,@GetMapping,@PostMapping,@Entity,@Repository等等。 这些是 Spring Boot 开发的基础。 - 结合实践学习: 最好的学习方式就是在实际项目中使用这些注解,遇到问题再深入研究。
- 查阅官方文档: Spring Boot 官方文档是学习注解最权威的资料,遇到不清楚的地方,一定要查阅官方文档。
希望这篇文章能帮助大家更好地理解 Spring Boot 注解,让你的 Spring Boot 开发更加高效、愉快!
如果你觉得这篇文章对你有帮助,欢迎点赞、评论、分享! 也欢迎关注我的 CSDN 博客,我会持续分享更多 Spring Boot 开发经验和技术干货。
我是 [你的 CSDN 昵称/名字],感谢阅读!
希望这次的风格更符合你的要求! 请注意,你需要将 [你的 CSDN 昵称/名字] 替换成你自己的 CSDN 昵称或名字。
同样,别忘了在 CSDN 编辑器中上传图片并替换链接。 祝你发布成功!
相关文章:
深入 Spring Boot 注解
深入 Spring Boot 注解:我的开发心得与常用注解详解 大家好,我是 [你的 CSDN 昵称/名字],一位热爱 Spring Boot 的技术博主。 在多年的 Spring Boot 开发实践中,我深深体会到注解的强大魅力。它们不仅让代码变得更简洁࿰…...
k8s环境部署
四台机器 分别是 k8s-master:172.25.254.100 k8s-node1:172.25.254.10 k8s-node2:172.25.254.20 docker-harbor:172.25.254.200 reg.timinglee.org 四台机器分别配置好网络和软件仓库 做好地址解析 scp -r /etc/hosts/ root17…...
CentOS 系统安装 docker 以及常用插件
博主用的的是WindTerm软件链接的服务器,因为好用 1.链接上服务器登入后,在/root/目录下 2.执行以下命令安装docker sudo yum install -y yum-utilssudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.reposudo…...
谷歌云服务器:服务器怎么安装???
谷歌云服务器:服务器怎么安装??? 以下是详细分步指南,帮助你在 Google Cloud Platform (GCP) 上快速创建并配置云服务器(Compute Engine 实例),并安装所需环境: 一、准备…...
Redis--Zset类型
目录 一、引言 二、介绍 三、命令 1.zadd 2.zrange,zrevrange,zrangebyscore 3.zcard,zcount 4.zpopmax,bzpopmax,zpopmin,bzpopmin 5.zrank,zrevrank,zscore 6.zrem,zremrangebyrank&a…...
《阿里云Data+AI:开启数据智能新时代》电子书上线啦!
本书整理了阿里云在DataAI领域的最新实践案例与深度洞察,涵盖电商、游戏、营销、数字内容等多个行业的成功经验,以及技术专家对数据库与AI融合趋势的专业解读。 通过理论与实践的结合,我们将共同探索DataAI如何成为企业智能化转型的核心驱动…...
图像处理篇---图像预处理
文章目录 前言一、通用目的1.1 数据标准化目的实现 1.2 噪声抑制目的实现高斯滤波中值滤波双边滤波 1.3 尺寸统一化目的实现 1.4 数据增强目的实现 1.5 特征增强目的实现:边缘检测直方图均衡化锐化 二、分领域预处理2.1 传统机器学习(如SVM、随机森林&am…...
Vue 3 事件总线详解:构建组件间高效通信的桥梁
Vue 3 事件总线详解:构建组件间高效通信的桥梁 为什么需要事件总线?使用 mitt 实现事件总线1. 安装 mitt2. 创建事件总线3. 在组件中使用事件总线发送端组件(例如 ComponentA.vue)接收端组件(例如 ComponentB.vue&…...
Golang编译器DIY,手搓 if err != nil { return err } 语法糖
前序 在go的社区里,下面这三行代码是被吐槽的最多的 if err ! nil {return err }从代码之整洁美观的角度看,这样的写法也是让人不舒服的。尤其是 当有很多错误需要处理的时候,就会发现通篇都是这三行。 所以想着看看修改一下编译器…...
图解多头注意力机制:维度变化一镜到底
目录 一、多头注意力机制概述二、代码实现1. pyTorch 实现2. tensorFlow实现 三、维度变化全流程详解1. 参数设定2. 维度变化流程图3. 关键步骤维度变化 四、关键实现细节解析1. 多头拆分与合并2. 注意力分数计算3. 掩码处理技巧 五、完整运行示例六、总结与常见问题1. 核心优势…...
.NET_Prism基本项目创建
Prism简述 模块(Module):独立的功能单元,可动态加载。依赖注入(Dependency Injection,DI):通过 IoC 容器(如 Unity、Autofac)管理模块之间的依赖关系。&#…...
BigEvent项目后端学习笔记(一)用户管理模块 | 注册登录与用户信息全流程解析(含优化)
📖 模块概述 用户管理模块是系统的核心基础模块,包含 注册、登录、用户信息维护 等功能。本模块涉及 JWT Token认证、密码加密存储、文件上传 等关键技术点,是理解前后端分离架构中安全与数据交互的典型实践。本篇对于原项目进行了代码优化&…...
[ISP] 人眼中的颜色
相机是如何记录颜色的,又是如何被显示器还原的? 相机通过记录RGB数值然后显示器显示RGB数值来实现颜色的记录和呈现。道理是这么个道理,但实际上各厂家生产的相机对光的响应各不相同,并且不同厂家显示器对三原色的显示也天差地别&…...
解锁MySQL 8.0.41源码调试:Mac 11.6+CLion 2024.3.4实战指南
文章目录 解锁MySQL 8.0.41源码调试:Mac 11.6CLion 2024.3.4实战指南前期准备环境搭建详细步骤安装 CLion安装 CMake 3.30.5准备 MySQL 8.0.41 源码配置 CMake 选项构建 MySQL 项目 调试环境配置与验证配置 LLDB 调试器启动调试验证调试环境 总结与拓展 解锁MySQL 8…...
celery入门
按照Celery 官方文档,用 Django Celery Redis 写的一个简单项目 如需转载,标记出处 环境准备 1. 安装依赖 pip install django celery redis 创建 Django 项目 1. 创建 Django 项目和 APP django-admin startproject myproject cd myproject python …...
关于xcode Project navigator/项目导航栏的一些说明
本文基于 xcode12.4 版本做说明 首先要明确一点,导航栏这里展示的并不是当前工程在电脑硬盘中的文件结构,它展示的是xxxxxx.xcodeproj/project.pbxproj文件(后文简.pbxproj文件)中的内容。我们在导航栏中的操作就是修改该文件,有些操作会修…...
深度解析扣减系统设计:从架构到实践
背景 在当今数字化业务蓬勃发展的时代,扣减系统在众多业务场景中扮演着关键角色。无论是电商平台的库存扣减,还是金融领域的资金扣减、积分系统的积分扣减,一个高效、可靠且数据一致的扣减系统都是业务稳健运行的基石。本文将深入探讨扣减系…...
视觉定位项目中可以任意修改拍照点位吗?
修改拍照点位不是那么简单 1. 背景2. 修改拍照点位意味着什么?3. 如何解决这个问题? 1. 背景 在视觉定位的项目中,会遇到这么一种情况:完成三步(9点标定,旋转中心标定,示教基准)之…...
深度学习常用操作笔记
深度学习常用操作笔记 指令报错cannot import name Config from mmcvImportError: cannot import name print_log from mmcvImportError: cannot import name init_dist from mmengine.runnerWARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNon…...
C++学习内存管理
1.概念的介绍 总括: 1. 栈(Stack) 存储内容: 局部变量(包括函数参数、非静态局部变量)。 函数调用的上下文信息(如返回地址、寄存器状态等)。 特点: 内存由编译器自动…...
git使用。创建仓库,拉取分支,新建分支开发
文章目录 安装 git自己新建仓库,进行代码管理合作开发的流程拉去主分支代码查看本地分支的状态查看远程分支查看远程的仓库信息本地分支切换切换并创建分支提交代码 made by NJITZX git 是一个版本控制工具,真正开发项目中是多个人开发一个项目的&#…...
itsdangerous加解密源码分析|BUG汇总
这是我这两天的思考 早知道密码学的课就不旷那么多了 纯个人见解 如需转载,标记出处 目录 一、官网介绍 二、事例代码 源码分析: 加密函数dump源码使用的函数如下: 解密 编辑 编辑 关于签名: 为什么这个数字签名没有…...
常见限流算法及实现
1. 固定窗口计数器(Fixed Window Counter) 原理:在固定时间窗口(如1分钟)内统计请求数,超过阈值则拒绝后续请求。优点:实现简单,内存占用低。缺点:存在窗口切换时的流量…...
计算机操作系统进程(4)
系列文章目录 第二章:进程的描述与控制 文章目录 系列文章目录前言一、临界区的概念和描述:二、硬件同步机制: 1.关中断2.利用Test-and-Set指令实现互斥3.利用Swap指令实现进程的互斥 总结 前言 上一篇我们仅仅讲了一点关于线程同步的概念&a…...
编程题《牛牛的链表删除》的python可以用非链表的方式
描述 牛牛从键盘输入了一个长度为 n 的数组,把这个数组转换成链表然后把链表中所有值是 x 的节点都删除。 输入描述: 第一行输入两个正整数 n 和 x 表示数组的长度和要删除的链表节点值 x 。 第二行输入 n 个正整数表示数组中每个元素的值。 输出描述&am…...
Certbot实现SSL免费证书自动续签(CentOS 7版 + Docker部署的nginx)
前置安装,可参考Certbot实现SSL免费证书自动续签(CentOS 7 nginx/apache) 如果是通过 Docker 运行 Nginx, certbot 无法直接检测到本地的 Nginx 配置。解决方案是 使用 standalone 模式 或 挂载 Webroot 方式获取 SSL 证书&…...
C++|构造函数和析构函数
一、构造函数 构造函数是一种特殊的成员函数,主要用于创建对象时对对象进行初始化操作,即专门用于构造新对象,并赋值对象的成员数据。 在 C 里,构造函数的名称和类名相同,并且没有返回类型。当创建类的对象时&#x…...
AI日报 - 2025年3月17日
🌟 今日概览(60秒速览) ▎🤖 AGI突破 | GPT-o1在卡内基梅隆大学数学考试中获满分,展示AI数学能力新高度 成本仅5美分/题,推理速度不到1分钟 ▎💼 商业动向 | Figure推出BotQ机器人制造设施&…...
不像人做的题————十四届蓝桥杯省赛真题解析(上)A,B,C,D题解析
题目A:日期统计 思路分析: 本题的题目比较繁琐,我们采用暴力加DFS剪枝的方式去做,我们在DFS中按照8位日期的每一个位的要求进行初步剪枝找出所有的八位子串,但是还是会存在19月的情况,为此还需要在CHECK函数…...
JavaScript 中 call 和 apply 的用法与区别
文章目录 前言一、 call 方法1.1 基本用法1.2 传递多个参数 二、apply 方法2.1 基本用法2.2 传递数组参数 三、call 和 apply 的区别四、实际应用场景4.1 借用方法4.2 继承与构造函数 五、总结 前言 在 JavaScript 中,call 和 apply 是两个非常重要的函数方法&…...
