Spring(三)容器-注入
一 自动注入@Autowire
代码实现:
package org.example.spring01.service;import org.springframework.stereotype.Service;@Service
public class UserService {}
package org.example.spring01.controller;import lombok.Data;
import lombok.ToString;
import org.example.spring01.bean.Person;
import org.example.spring01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;import java.util.List;
import java.util.Map;@ToString
@Data
@Controller
public class UserController {/*** 自动注入 原理:Spring调用容器的getBean方法* @Autowired* 只有且只找到一个,直接注入,名字无所谓* 如果找到多个在按照名称去找,变量名就是名字*/@AutowiredUserService userService;@AutowiredList<Person> personList;@AutowiredMap<String,Person> personMap;}
package org.example.spring01;import org.example.spring01.controller.UserController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class Spring01Application {public static void main(String[] args) {// 启动springboot应用ConfigurableApplicationContext ioc = SpringApplication.run(Spring01Application.class, args);System.out.println("run = " + ioc);UserController bean = ioc.getBean(UserController.class);System.out.println("bean = " + bean);}
}
二 默认首选/指定Bean@Primary @Qualifier
1 概述:
-
@Primary
:“默认选我”,简化多数场景的依赖注入。 -
@Qualifier
:“点名要谁”,精准控制依赖的选择。
2 当某个 Bean 被标记为
@Primary
,Spring 的依赖注入规则变为:
-
优先选择
@Primary
的 Bean,无论字段名如何变化。 -
忽略属性名匹配,直接注入
@Primary
标记的 Bean。
3 在没有
@Primary
时,Spring 按以下顺序解决依赖:
-
按类型匹配:寻找与字段类型一致的 Bean。
-
按名称匹配:如果有多个同类型 Bean,尝试将字段名与 Bean 的名称(ID)匹配。
@Primary标记一个Bean,然后在注入时用@Autowired,这时候会自动选择@Primary的;或者当有多个Bean时,用@Qualifier指定名称来注入。
当同时存在 @Primary
和 @Qualifier
时,@Qualifier
的优先级更高:
代码实现:
// @Primary默认组件,不说明Person具体就是这个@Primary@Bean("LiSi")public Person lisi() {Person person = new Person();person.setAge(18);person.setGender("男");person.setName("李四");return person;}
代码实现:
package org.example.spring01.service;import lombok.Data;
import org.example.spring01.bean.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Data // Lombok 注解,自动生成 getter/setter/toString 等方法
@Service // Spring 注解,标记为服务层 Bean
public class UserService {//如果容器中这种组件有多个,则使用@Qualifier注解精确指定注入的组件名@Qualifier("ZhangSan") // 指定注入名为 "ZhangSan" 的 Bean@Autowired // 自动注入依赖Person person; // 依赖的 Person 对象
}
三 自动注入@Resource
在选择使用哪一个注解时,可以根据项目的具体需求和个人偏好来决定。在许多情况下,这两种注解可以互换使用,特别是在只有一个符合条件的bean的情况下。
使用场景:
- 如果项目完全基于Spring框架,那么@Autowired可能是更自然的选择;
- 而如果是在Java EE环境中,或者你更倾向于通过名称来引用bean,那么@Resource可能更适合。
参数
- @Autowired 支持一个 required 参数,默认值为 true。设置为 false 时,表示即使没有找到对应的bean也不会报错。
- @Resource 支持 name 和 type 属性,可以明确指定要注入的bean的名称和类型。
注入方式
- @Autowired 支持构造器注入、设值方法注入以及字段注入。
- @Resource 主要用于字段注入和设值方法注入,不直接支持构造器注入。
四 构造器注入
在 Spring 框架中,构造器自动注入(Constructor Injection) 是一种通过类的构造方法(Constructor)自动注入依赖项的方式。它不仅是依赖注入(DI)的核心模式之一,更是 Spring 官方推荐的最佳实践。以下是其核心概念、优势及使用场景的详细解析:
1. 什么是构造器注入?
-
定义:通过类的构造方法参数传递依赖项,由 Spring 容器自动将匹配的 Bean 注入到参数中。
-
自动注入:从 Spring 4.3 开始,如果类只有一个构造方法,
@Autowired
注解可以省略,Spring 会默认使用该构造方法注入依赖。
@Service
public class UserService {private final UserRepository userRepository;private final EmailService emailService;// Spring 自动注入依赖(无需 @Autowired)public UserService(UserRepository userRepository, EmailService emailService) {this.userRepository = userRepository;this.emailService = emailService;}
}
2、构造器注入的优势
1. 依赖不可变性
-
final
字段:依赖项通过构造方法赋值后,可以声明为final
,确保对象初始化后不可变。 -
线程安全:避免依赖在运行时被意外修改,提升代码健壮性。
2. 明确依赖关系
-
强制依赖:构造方法参数明确声明了类的所有必需依赖,避免依赖缺失。
-
启动时检查:如果 Spring 容器中缺少某个依赖,应用会在启动时直接报错(而非运行时才暴露问题)。
3. 避免循环依赖
-
设计约束:如果两个类通过构造器注入相互依赖,Spring 会直接抛出
BeanCurrentlyInCreationException
,迫使开发者重构代码,解决循环依赖问题。
4. 更好的测试性
-
无需容器:在单元测试中,可以直接通过构造方法传入 Mock 对象,无需依赖 Spring 容器或反射。
-
代码透明:依赖关系一目了然,便于理解类的职责。
3、使用场景
1. 强依赖场景
-
类的核心功能依赖某个组件(如数据库访问层
UserRepository
)。 -
示例:服务类、控制器、数据访问对象(DAO)。
2. 需要不可变对象的场景
-
配置类、DTO(数据传输对象)、工具类等,确保依赖不会被修改。
3. Spring Boot 项目
-
Spring Boot 强烈推荐构造器注入,尤其是在结合 Lombok 的
@RequiredArgsConstructor
时,可以大幅简化代码。
4、实现方式
1. 隐式自动注入(Spring 4.3+)
-
如果类只有一个构造方法,Spring 会自动选择它进行注入,无需
@Autowired
。
@Service
public class PaymentService {private final PaymentGateway paymentGateway;// 无需 @Autowiredpublic PaymentService(PaymentGateway paymentGateway) {this.paymentGateway = paymentGateway;}
}
2. 显式指定构造方法
-
如果类有多个构造方法,需用
@Autowired
指定使用哪一个。
@Service
public class OrderService {private final InventoryService inventoryService;private final Logger logger;@Autowired // 显式标记要使用的构造方法public OrderService(InventoryService inventoryService) {this(inventoryService, LoggerFactory.getLogger(OrderService.class));}// 辅助构造方法public OrderService(InventoryService inventoryService, Logger logger) {this.inventoryService = inventoryService;this.logger = logger;}
}
3. 结合 Lombok 简化代码
-
使用
@RequiredArgsConstructor
自动生成包含final
字段的构造方法。
@Service
@RequiredArgsConstructor // 自动生成构造方法
public class NotificationService {private final EmailService emailService;private final SmsService smsService;
}
相关文章:

Spring(三)容器-注入
一 自动注入Autowire 代码实现: package org.example.spring01.service;import org.springframework.stereotype.Service;Service public class UserService {}package org.example.spring01.controller;import lombok.Data; import lombok.ToString; import org.…...

剧本杀门店预约小程序:市场发展下的刚需
在剧本杀爆发式增长下,门店数字化运营的模式正在市场中逐渐展开,线下门店的竞争方向已发生了全新转变! 目前,数字化发展已经成为了消费市场的刚需,利用网络的便捷性提高服务,优化运营,提高自身…...

stable-diffusion-webui 加载模型文件
背景 stable-diffusion-webui 安装完毕后,默认的模型生成的效果图并不理想,可以根据具体需求加载指定的模型文件。国内 modelscope 下载速度较快,以该站为例进行介绍 操作步骤 找到指定的模型文件 在 https://modelscope.cn/models 中查找…...

Ubuntu20.04双系统安装及软件安装(十一):向日葵远程软件
Ubuntu20.04双系统安装及软件安装(十一):向日葵远程软件 打开向日葵远程官网,下载图形版本: 在下载目录下打开终端,执行: sudo dpkg -i SunloginClient(按tab键自动补全)出现报错: …...

华为云 | 快速搭建DeepSeek推理系统
DeepSeek(深度求索)作为一款国产AI大模型,凭借其高性能、低成本和多模态融合能力,在人工智能领域崛起,并在多个行业中展现出广泛的应用潜力。 如上所示,在华为云解决方案实践中,华为云提供的快速…...

printf 与前置++、后置++、前置--、后置-- 的关系
# 前置和前置-- 先看一段代码 大家是不是认为printf输出的是 2 3 3 2 1 1 但是实际输出的是 3 3 3 1 1 1 在这两行printf函数代码里,编译器会先计算 a 和 --a 的值,然后再 从右向左 开始输出。 printf函数中,如果有多个…...

centos7操作系统下安装docker,及查看docker进程是否启动
centos7下安装docker,需要用到的yun命令 (yum命令用于添加卸载程序) 1.设置仓库: yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 2.安装 Docker Engine-Community yum in…...
【向量数据库Weaviate】 和Elasticsearch的区别
Weaviate 和 Elasticsearch 是两种不同类型的数据库,设计目标和应用场景有显著差异。以下是它们的核心区别和适用场景的详细对比: 1. 设计目标与核心能力 维度WeaviateElasticsearch核心能力向量数据库 图数据库(语义搜索优先)全…...

深度学习-大白话解释循环神经网络RNN
目录 一、RNN的思想 二、RNN的基本结构 网络架构 关键点 三、RNN的前向传播 四、RNN的挑战:梯度爆炸和梯度消失 问题分析 示例推导 五、LSTM:RNN的改进 核心组件 网络架构 3. LSTM 的工作流程 4. 数学公式总结 5. LSTM 的优缺点 优点 缺点 6. LSTM 的…...

python3.13安装教程【2025】python3.13超详细图文教程(包含安装包)
文章目录 前言一、python3.13安装包下载二、Python 3.13安装步骤三、Python3.13验证 前言 本教程将为你详细介绍 Python 3.13 python3.13安装教程,帮助你顺利搭建起 Python 3.13 开发环境,快速投身于 Python 编程的精彩实践中。 一、python3.13安装包下…...

RocketMQ的运行架构
目录 1. 核心组件(1) NameServer(2) Broker(3) Producer(4) Consumer 2. 消息流转流程3. 高可用机制4. 扩展性与负载均衡5.容错机制5. 特殊功能支持6. 典型部署架构总结 RocketMQ 是一款高性能、高可靠的分布式消息中间件,其运行架构设计为分布式、可扩展、高可用的…...
SLAM文献之-DROID-SLAM: Deep Visual SLAM for Monocular, Stereo, and RGB-D Cameras
DROID-SLAM 是一种结合深度学习与传统视觉SLAM技术的先进算法,其核心目标是通过端到端可训练的深度神经网络来实现高精度的相机位姿估计和稠密三维重建。与传统SLAM方法不同,DROID-SLAM采用深度学习网络来估计深度信息,提供更高的精度与鲁棒性…...
nano 是 Linux 系统中的一个 命令行文本编辑器
nano 是 Linux 系统中的一个 命令行文本编辑器,用于在终端中直接编辑文本文件。它相比 vi 或 vim 更加简单易用,适合新手操作。 具体解释: 在你给出的命令 sudo nano /etc/nfs.conf 中: sudo:以管理员权限运行命令&a…...
JAVA毕设项目-基于SSM框架的百色学院创新实践学分认定系统源码+设计文档
文末获取源码数据库文档 感兴趣的可以先收藏,有毕设问题,项目以及论文撰写等问题都可以和博主沟通,尽最大努力帮助更多的人! 百色学院创新实践学分认定系统设计与实现 摘 要 本百色学院创新实践学分认定系统是针对目前实践学分认定…...
Unity3D 刚体动力学(Rigidbody Dynamics)详解
引言 在Unity3D中,刚体(Rigidbody)是实现物理模拟的核心组件之一。刚体动力学(Rigidbody Dynamics)是指通过物理引擎模拟物体的运动、碰撞、重力等行为。Unity3D内置了强大的物理引擎,开发者可以通过刚体组…...

深入理解Spring Cloud Gateway网关原理及使用
1、网关简介 网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。 2、Gateway简介 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。 Spri…...

ESP32+Mixly-WiFi
#include <WiFi.h> #include <TimeLib.h> #include <NtpClientLib.h>int8_t timeZone 8; // 时区设置,东八区为8 const PROGMEM char *ntpServer "ntp1.aliyun.com"; // NTP服务器地址void setup(){Serial.begin(9600); //初始化串口…...
Spring AI:开启Java开发的智能新时代
目录 一、引言二、什么是 Spring AI2.1 Spring AI 的背景2.2 Spring AI 的目标 三、Spring AI 的核心组件3.1 数据处理3.2 模型训练3.3 模型部署3.4 模型监控 四、Spring AI 的核心功能4.1 支持的模型提供商与类型4.2 便携 API 与同步、流式 API 选项4.3 将 AI 模型输出映射到 …...
Github-介绍
GitHub 是一个基于 Git 版本控制系统的代码托管平台,广泛用于开源项目、团队协作、代码管理等方面。它让开发者能够上传、分享、修改、协作、跟踪代码的更改。 1. GitHub 的基本功能: 代码托管:GitHub 提供云端存储代码的功能,可…...

爬虫系列之【数据解析之正则】《二》
目录 前言 一、正则基本使用 1.1 导包 1.2 接口方法 1.3 换行匹配问题 二、实战案例 完整代码 前言 在爬虫工作中,我们主要会遇到两种类型的文本数据: JSON格式数据 HTML文档数据 对于JSON字符串数据,通常使用Python的字典操作进行键…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...