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

5. Spring DI 依赖注入(构造器、Setter)

核心概念

Spring 依赖注入(DI)是 IoC 核心实现,核心分为构造器注入(推荐)和Setter 注入两种方式,以下从「XML 配置」「注解配置」双维度整理,兼顾传统写法与主流语法糖

构造器注入(Constructor Injection)

核心思想

通过类的构造方法传入依赖对象,Spring 容器创建 Bean 时调用构造方法完成注入

  • ✅ 优点:确保依赖非空,Bean 创建后即完整;适合必选核心依赖(如 Service/Repository)
  • ❌ 缺点:无法解决循环依赖;多参数时配置稍繁琐

XML 配置方式(纯配置文件)

基础结构

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1. 定义被依赖的 Bean --> <bean id="userService" class="com.example.service.impl.UserServiceImpl"/> <!-- 2. 构造器注入 UserController --> <bean id="userController" class="com.example.controller.UserController"> <!-- 方式1:按参数索引(不推荐,参数顺序变易出错) --> <constructor-arg index="0" ref="userService"/> <!-- 方式2:按参数类型(推荐,精准匹配) --> <!-- <constructor-arg type="com.example.service.UserService" ref="userService"/> --> <!-- 方式3:按参数名称(推荐,最直观) --> <!-- <constructor-arg name="userService" ref="userService"/> --> <!-- 扩展:注入基本类型参数 --> <!-- <constructor-arg name="version" value="1.0.0"/> --> </bean> </beans>

核心语法

标签属性作用示例
index构造方法参数索引(从 0 开始)index="0"
type构造方法参数全类名type="com.example.service.UserService"
name构造方法参数名称name="userService"
ref引用容器中已定义的 Bean(对象类型)ref="userService"
value注入基本类型 / 字符串value="1.0.0"

注解配置方式(主流语法糖)

基础写法(无 Lombok)

// 1. 被依赖的 Service(@Service 声明为 Bean) package com.example.service.impl; import com.example.service.UserService; import org.springframework.stereotype.Service; @Service // Bean 名称默认:userServiceImpl public class UserServiceImpl implements UserService {} // 2. 控制器类(构造器注入) package com.example.controller; import com.example.service.UserService; import org.springframework.stereotype.Controller; @Controller public class UserController { // 必选依赖建议用 final 修饰 private final UserService userService; // 语法糖:单个构造方法 → 无需加 @Autowired public UserController(UserService userService) { this.userService = userService; } // 多构造方法时 → 显式加 @Autowired 指定注入的构造器 // @Autowired // public UserController(UserService userService, String version) { // this.userService = userService; // } }

简化写法(Lombok 语法糖)

package com.example.controller; import com.example.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; @Controller @RequiredArgsConstructor // 自动生成 final 变量的构造器,替代手动编写 public class UserController { private final UserService userService; // 自动注入 }

Setter 注入(Setter Injection)

核心思想

通过类的setXxx()方法传入依赖对象,Spring 先创建 Bean 实例,再调用 Setter 方法完成注入

  • ✅ 优点:支持可选依赖,可动态修改;能解决循环依赖(Spring 三级缓存)
  • ❌ 缺点:Bean 创建后可能缺依赖,无法保证完整性

XML 配置方式(纯配置文件)

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1. 定义被依赖的 Bean --> <bean id="userService" class="com.example.service.impl.UserServiceImpl"/> <!-- 2. Setter 注入 UserController --> <bean id="userController" class="com.example.controller.UserController"> <!-- 注入对象类型:name 对应 Setter 方法名(setUserService → userService) --> <property name="userService" ref="userService"/> <!-- 注入基本类型:直接赋值 --> <property name="version" value="1.0.0"/> </bean> </beans>

核心语法

标签属性作用示例
name对应 Setter 方法名(去掉 set 前缀,首字母小写)name="userService"
ref引用容器中已定义的 Bean(对象类型)ref="userService"
value注入基本类型 / 字符串value="1.0.0"

注解配置方式(主流语法糖)

package com.example.controller; import com.example.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class UserController { // 语法糖1:@Autowired 直接加在成员变量(跳过 Setter 方法) @Autowired // 多同类型 Bean 时,用 @Qualifier 指定名称 @Qualifier("userServiceImpl") private UserService userService; // 语法糖2:@Resource(JDK 注解,按名称注入) // @Resource(name = "userService") // private UserService userService; // 传统写法:@Autowired 加在 Setter 方法 // public void setUserService(UserService userService) { // this.userService = userService; // } }

两种注入方式对比

特性构造器注入Setter 注入
依赖必要性必选(构造时必须传入)可选(可后续设置)
Bean 完整性创建后即完整初始化后可能缺依赖
循环依赖无法解决可解决(Spring 三级缓存)
推荐场景核心必选依赖(Service/Repository)可选依赖(配置参数 / 工具类)
XML 核心标签<constructor-arg><property>
注解核心语法糖@RequiredArgsConstructor@Autowired/@Resource

关键注意事项

  1. 注解注入时,@Autowired先按类型匹配,再按名称;@Resource先按名称匹配,再按类型
  2. XML 配置中,Bean 的id必须唯一,class属性需写完整包名 + 类名
  3. 实际开发优先用构造器注入管理核心依赖,Setter 注入仅用于可选依赖

总结

  1. Spring DI 核心为构造器注入(必选依赖)和 Setter 注入(可选依赖),均支持 XML 纯配置、注解两种实现方式
  2. 构造器注入推荐用注解 + Lombok(@RequiredArgsConstructor),XML 中优先用type/name匹配参数
  3. Setter 注入注解版可直接在成员变量加@Autowired/@Resource,XML 中通过<property>匹配 Setter 方法名
http://www.cnnetsun.cn/news/1344827.html

相关文章:

  • Robotstudio6.08坐标实用教程
  • 西门子1200与欧姆龙E5cc温控器通讯控制全解析
  • testtest
  • CNN - BiLSTM - Attention分类:新手友好的多分类实战
  • 智慧农业农业智能诊断、植物保护 葡萄叶片病害分割数据集 基于 PyTorch + Torchvision 的 DeepLabV3+ 训练葡萄叶片分割数据集
  • 移动端适配的隐藏坑:这5个错误90%的人在犯
  • 【已解决】java文件未被识别 显示咖啡杯图标
  • Python学习路线图(如果你计划快速的学习掌握python)
  • 文献检索如何限制文献类型(期刊 / 会议 / 综述)?3 个技巧让结果更精准
  • 欧姆龙FinsUdp协议报文例子
  • 【最新版】2026年OpenClaw阿里云5分钟搭建及使用保姆级教程
  • 文华财经精准识别高低点20日均线 + 极值标注指标编写教程
  • Java入门第154课——Oracle 数据库入门与基础操作
  • 2026年中秋手抄报模板返工一次后,我总结的模板筛选与修改经验
  • 在AI Agent爆发前夜,我们必须对自己进行一次“颠覆”
  • Kotlin的reified泛型:在运行时保留类型信息
  • 代差级突破|2026 女性经期新选择:专属特殊膳食饮品深度评测
  • android studio安装及配置jdk17
  • Git误删急救:30秒拯救你的代码
  • PhpStorm下载、安装、配置教程
  • Redis值数据类型——sorted set
  • 双令牌机制:让认证更安全、体验更流畅
  • 互联网大厂Java面试实战:以智慧物流场景为例深入探讨Spring Boot、微服务与Redis缓存
  • Metasploitable靶机的下载与安装
  • Claude国内镜像站实测:可扩展监督与宪法AI,推理架构的范式革命
  • OpenClaw 高效配置与集成指南:从模型选择到 API 对接
  • 游戏盾终极奥义:湘情盾“源站隐身”与“报文基因”实战解析
  • Claude Code超详细完整指南附最佳实践(最新版2026年,可接入GLM)
  • 3.17打卡day31
  • KIHU快狐|带API协议户外液晶显示器支持第三方平台对接