当前位置: 首页 > news >正文

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 的依赖注入规则变为:

  1. 优先选择 @Primary 的 Bean,无论字段名如何变化。

  2. 忽略属性名匹配,直接注入 @Primary 标记的 Bean。

3 在没有 @Primary 时,Spring 按以下顺序解决依赖:

  1. 按类型匹配:寻找与字段类型一致的 Bean。

  2. 按名称匹配:如果有多个同类型 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 代码实现&#xff1a; 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.…...

剧本杀门店预约小程序:市场发展下的刚需

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

stable-diffusion-webui 加载模型文件

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

Ubuntu20.04双系统安装及软件安装(十一):向日葵远程软件

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

华为云 | 快速搭建DeepSeek推理系统

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

printf 与前置++、后置++、前置--、后置-- 的关系

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

centos7操作系统下安装docker,及查看docker进程是否启动

centos7下安装docker&#xff0c;需要用到的yun命令 &#xff08;yum命令用于添加卸载程序&#xff09; 1.设置仓库&#xff1a; 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 是两种不同类型的数据库&#xff0c;设计目标和应用场景有显著差异。以下是它们的核心区别和适用场景的详细对比&#xff1a; 1. 设计目标与核心能力 维度WeaviateElasticsearch核心能力向量数据库 图数据库&#xff08;语义搜索优先&#xff09;全…...

深度学习-大白话解释循环神经网络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安装教程&#xff0c;帮助你顺利搭建起 Python 3.13 开发环境&#xff0c;快速投身于 Python 编程的精彩实践中。 一、python3.13安装包下…...

RocketMQ的运行架构

目录 1. 核心组件(1) NameServer(2) Broker(3) Producer(4) Consumer 2. 消息流转流程3. 高可用机制4. 扩展性与负载均衡5.容错机制5. 特殊功能支持6. 典型部署架构总结 RocketMQ 是一款高性能、高可靠的分布式消息中间件&#xff0c;其运行架构设计为分布式、可扩展、高可用的…...

SLAM文献之-DROID-SLAM: Deep Visual SLAM for Monocular, Stereo, and RGB-D Cameras

DROID-SLAM 是一种结合深度学习与传统视觉SLAM技术的先进算法&#xff0c;其核心目标是通过端到端可训练的深度神经网络来实现高精度的相机位姿估计和稠密三维重建。与传统SLAM方法不同&#xff0c;DROID-SLAM采用深度学习网络来估计深度信息&#xff0c;提供更高的精度与鲁棒性…...

nano 是 Linux 系统中的一个 命令行文本编辑器

nano 是 Linux 系统中的一个 命令行文本编辑器&#xff0c;用于在终端中直接编辑文本文件。它相比 vi 或 vim 更加简单易用&#xff0c;适合新手操作。 具体解释&#xff1a; 在你给出的命令 sudo nano /etc/nfs.conf 中&#xff1a; sudo&#xff1a;以管理员权限运行命令&a…...

JAVA毕设项目-基于SSM框架的百色学院创新实践学分认定系统源码+设计文档

文末获取源码数据库文档 感兴趣的可以先收藏&#xff0c;有毕设问题&#xff0c;项目以及论文撰写等问题都可以和博主沟通&#xff0c;尽最大努力帮助更多的人&#xff01; 百色学院创新实践学分认定系统设计与实现 摘 要 本百色学院创新实践学分认定系统是针对目前实践学分认定…...

Unity3D 刚体动力学(Rigidbody Dynamics)详解

引言 在Unity3D中&#xff0c;刚体&#xff08;Rigidbody&#xff09;是实现物理模拟的核心组件之一。刚体动力学&#xff08;Rigidbody Dynamics&#xff09;是指通过物理引擎模拟物体的运动、碰撞、重力等行为。Unity3D内置了强大的物理引擎&#xff0c;开发者可以通过刚体组…...

深入理解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; // 时区设置&#xff0c;东八区为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 版本控制系统的代码托管平台&#xff0c;广泛用于开源项目、团队协作、代码管理等方面。它让开发者能够上传、分享、修改、协作、跟踪代码的更改。 1. GitHub 的基本功能&#xff1a; 代码托管&#xff1a;GitHub 提供云端存储代码的功能&#xff0c;可…...

爬虫系列之【数据解析之正则】《二》

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

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...