IOC与DI

IOC与DI

2026年5月17日·#后端基础前端/SpringBoot/Java·868 字 4 分钟
浏览量加载中...
AI 摘要

Spring框架控制反转(IOC)与依赖注入(DI)的核心概念、注解用法及多种注入方式

IOC与DI#

定义#

控制反转(IOC,Inversion Of Control):对象的创建控制权由程序自身转移到外部(容器),即由Spring IOC容器负责创建和管理对象。

依赖注入(DI,Dependency Injection):容器为应用程序提供运行时所需的资源(对象)。

Bean对象:IOC容器中创建和管理的对象。

核心思想#

  • 提供一个容器,容器中存储bean对象
  • Controller程序从容器中获取所需类型的对象,而非直接new
  • 将对象的创建权从程序员主动创建转移到容器管理

语法/用法#

1. Bean的声明(IOC)#

使用注解将类交给IOC容器管理:

注解说明位置
@Component声明bean的基础注解不属于以下三类时使用
@Controller@Component的衍生注解控制层类
@Service@Component的衍生注解业务层类
@Repository@Component的衍生注解数据访问层类

示例:

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
// ...
}
@Repository
public class UserDaoImpl implements UserDao {
// ...
}
@RestController
public class UserController {
@Autowired
private UserService userService;
// ...
}

2. 组件扫描#

  • 声明bean的四大注解需要被@ComponentScan扫描才能生效
  • @SpringBootApplication注解已包含@ComponentScan,默认扫描启动类所在包及其子包
  • 因此只需将业务类放在启动类所在包的子包中即可

3. @Autowired依赖注入(DI)三种方式#

方式一:属性注入

@RestController
public class UserController {
@Autowired
private UserService userService;
}
  • 优点:代码简洁、快速开发
  • 缺点:隐藏了类之间的依赖关系、可能破坏封装性

方式二:构造函数注入(官方推荐)

@RestController
public class UserController {
private final UserService userService;
@Autowired //如果只有一个构造函数,@Autowired可以省略
public UserController(UserService userService) {
this.userService = userService;
}
}
  • 优点:依赖关系清晰、代码安全性高
  • 注意:如果只有一个构造函数,@Autowired可省略

方式三:setter注入

@RestController
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
  • 优点:保持封装性、依赖关系清晰
  • 缺点:需要额外编写setter方法

4. 多实现类注入冲突解决方案#

当IOC容器中存在多个相同类型的bean时,使用以下方式指定:

方案用法说明
@Primary加在实现类上确定默认实现
@Qualifier配合@Autowired使用按bean名称指定注入
@ResourceJDK提供,name属性指定bean名称按名称注入
// 方案一
@Primary
@Service
public class UserServiceImpl implements UserService { }
// 方案二
@Qualifier("userServiceImpl")
@Autowired
private UserService userService;
// 方案三
@Resource(name = "userServiceImpl")
private UserService userService;

常见场景#

  1. 解耦层与层之间的依赖:Controller不再直接new Service,Service不再直接new Dao
  2. 灵活切换实现类:当业务需求变更需要替换Service实现时,只需将新实现类交给IOC容器管理,无需修改Controller代码
  3. 依赖管理:Spring容器统一管理对象的生命周期和依赖关系

注意事项#

  1. 声明控制器bean只能用@Controller(在SpringBoot集成Web开发中)
  2. bean名称:通过注解的value属性指定bean名字,默认类名首字母小写
  3. @Autowired vs @Resource:@Autowired是Spring框架注解,默认按类型注入;@Resource是JDK注解,按名称注入
  4. 官方推荐构造函数注入方式(更规范),但企业项目中属性注入也很常见(更简洁高效)
  5. 只有被组件扫描到的注解才会生效,确保业务类在启动类的子包路径下

相关链接#

最后更新于 2026-05-17,距今已过 92 天

部分内容可能已过时

评论区

[ 标签 ]
# AI5# AI 编程2# AI工具1# Ajax2# Apifox1# AstrBot2# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# CloudFlare2# Cloudflare1# CloudFlare-ImgBed1# coc3# CSS6# DeepSeek2# deepseek2# DELETE1# Docker1# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML6# HTTP2# Java23# java13# JavaScript5# JDBC3# JSON1# JUnit1# Logback1# Maven6# Mybatis1# MyBatis4# MySQL6# MySql1# NapCat1# Obsidian3# OpenCode3# ORM1# PathVariable1# PicGo1# py2# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot11# SQL2# Svelte2# TailwindCSS1# Telegram2# Tlias2# Vercel1# Vue7# Waline3# WebDAV1# Web基础6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档9# 写作1# 刷步数1# 前端32# 动态1# 动漫1# 单词2# 博客6# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 图床4# 地图1# 备份1# 奇思妙想1# 存储1# 学习方法1# 宝塔面板3# 宝宝9# 导航栏1# 工具2# 开发1# 开发规范1# 开心1# 影视1# 微信1# 性能优化2# 总结1# 想法7# 感悟9# 指南1# 插件3# 故障排除1# 效率工具2# 教程7# 数据库10# 斩神1# 日常60# 日志框架1# 朋友圈1# 朱元璋1# 模板1# 测试1# 游戏1# 生活迁移1# 电影2# 碎碎念1# 视觉识别1# 网络教室1# 羊毛1# 脚本1# 脚本工具1# 自动化2# 蓝奏云1# 订阅推荐1# 记录1# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载1# 运动1# 部落冲突1# 配置1# 随机图1# 音乐3# 音标1# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]
工具