三层架构
Controller(控制层)
- 角色定位:请求处理的入口
- 核心职责:接收前端发送的请求,对请求进行处理后响应数据
Service(业务逻辑层)
- 角色定位:业务逻辑的处理中心
- 核心职责:处理具体的业务逻辑
Dao(数据访问层,又称持久层)
- 角色定位:数据操作的封装层(全称 Data Access Object)
- 核心职责:负责数据访问操作,包含数据的增加、删除、修改、查询
Spring Boot 三种依赖注入方式核心笔记
核心共性
三种注入方式均由Spring 容器自动查找对应 Bean完成赋值,无需手动创建依赖对象。
一、构造器注入(官方推荐)
核心特性
优势
- 双重非空保障:编译期(final)+ 启动期(容器校验),运行时绝对无空指针;
- 依赖关系完全显性,看构造方法即可明确类的依赖,代码可读性 / 可维护性高。
代码示例
@Service
public class UserService {
private final UserDao userDao; // final修饰,编译期强制赋值
// 无@Autowired,Spring自动注入(2.6+)
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
二、Set 注入
核心特性
风险
注入失败无任何启动提示,调用依赖方法时直接触发空指针异常,问题多在运行时暴露。
代码示例
@Service
public class UserService {
private UserDao userDao; // 不可加final
// 无@Autowired则不注入,变量为null
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
三、属性注入
核心特性
风险
注入失败诱因最多(忘加注解、无匹配 Bean、注入时机过早),空指针风险极高,是三者中最不推荐的方式。
代码示例
@Service
public class UserService {
// 忘加@Autowired则不注入,变量为null
@Autowired
private UserDao userDao; // 不可加final
}
四、核心差异对比(核心考点 / 开发重点)
| 构造器注入 | ✅ 推荐 | 项目直接启动失败 | 无 | 完全显性 | 推荐 |
| Set 注入 | ❌ 不能 | 变量为 null,运行时报错 | 高 | 部分显性 | 不推荐 |
| 属性注入 | ❌ 不能 | 变量为 null,运行时报错 | 极高 | 完全隐性 | 不推荐 |
五、核心结论
Spring @Autowired 多实现类注入(兜底匹配)
一、核心场景
当一个接口(如UserService)有多个实现类(如UserServiceImpl、UserServiceImpl2),用@Autowired注入时,未报错的核心是触发了 Spring 的「名称兜底匹配机制」。
二、关键前提规则
1. 实现类的默认 Bean 名规则
被@Service(无自定义名称)标注的实现类,Spring 自动生成 Bean 名:类名首字母小写(例:UserServiceImpl→userServiceImpl、UserServiceImpl2→userServiceImpl2)。
2. @Autowired 注入优先级(核心)
三、场景不报错 / 报错的直接原因
1. 不报错(变量名 = Bean 名)
Controller 中注入变量名userServiceImpl,与UserServiceImpl的默认 Bean 名完全匹配,Spring 精准注入,无冲突。
2. 报错(变量名≠任何 Bean 名)
变量名改为u后,无法通过名称匹配任何实现类的 Bean,Spring 无法确定注入哪个,直接抛出异常。
四、解决 “变量名任意取仍不报错” 的方法
若想变量名自定义(如u),用@Qualifier明确指定 Bean 名即可,示例:
@Autowired
@Qualifier("userServiceImpl") // 指定要注入的Bean名
private UserService u; // 变量名可任意,不影响注入
五、核心结论
Spring DI(依赖注入)多 Bean 冲突解决方案核心笔记
一、核心问题背景
@Autowired默认按类型(byType) 注入,当接口存在多个实现类(如UserServiceImpl、UserServiceImpl2)时,Spring 容器中会有多个同类型 Bean,直接注入会抛出NoUniqueBeanDefinitionException异常,提示 “需要单个 Bean 但找到多个”。
二、三种核心解决方案
方案 1:@Primary(指定默认首选 Bean)
核心逻辑
在多个同类型 Bean 中,给优先级最高的实现类标注@Primary,Spring 会优先注入该 Bean,无需修改注入端代码。
代码示例
// 实现类端:标注@Primary,设为默认首选
@Service
@Primary
public class UserServiceImpl implements UserService {
// 业务方法
@Override
public List<User> list() {
// 逻辑实现
}
}
// Controller端:直接注入,Spring自动选@Primary的Bean
@RestController
public class UserController {
@Autowired
private UserService userService; // 注入UserServiceImpl
}
适用场景
有明确 “主实现类”,其他实现类为备用的场景(如默认用 MySQL 实现,Redis 实现为兜底)。
方案 2:@Qualifier(精准指定 Bean 名)
核心逻辑
配合@Autowired使用,通过@Qualifier("Bean名")明确指定要注入的 Bean 名称(Bean 名默认是实现类首字母小写),精准匹配。
代码示例
// 实现类端:无需额外标注,用默认Bean名
@Service // Bean名:userServiceImpl
public class UserServiceImpl implements UserService {}
@Service // Bean名:userServiceImpl2
public class UserServiceImpl2 implements UserService {}
// Controller端:用@Qualifier指定Bean名
@RestController
public class UserController {
@Autowired
@Qualifier("userServiceImpl") // 明确指定注入该Bean
private UserService userService; // 变量名可任意,不影响匹配
}
适用场景
需要灵活切换不同实现类的场景(如按需注入 MySQL/Redis 实现),是最常用的方案。
方案 3:@Resource(按名称注入,JDK 原生)
核心逻辑
@Resource是 JDK 原生注解,默认按名称(byName) 注入,通过name属性指定 Bean 名,无需搭配@Autowired。
代码示例
// 实现类端:默认Bean名
@Service // Bean名:userServiceImpl
public class UserServiceImpl implements UserService {}
// Controller端:用@Resource指定Bean名
@RestController
public class UserController {
@Resource(name = "userServiceImpl") // 直接指定Bean名
private UserService userService; // 注入UserServiceImpl
}
关键区别
与@Autowired+@Qualifier相比:
- @Resource是 JDK 注解,@Autowired是 Spring 注解;
- @Resource默认 byName,@Autowired默认 byType(需 @Qualifier 兜底 byName)。
@Resource 与 @Autowired+@Qualifier 核心执行逻辑总结
一、核心共性
两者均用于解决多 Bean 注入冲突,最终都要求「Bean 名匹配 + 类型兼容」才能成功注入,不存在 “不校验类型” 的情况。
二、核心差异(匹配顺序是关键)
1. @Resource 执行逻辑(先名后型,名为主、型为兜底)
2. @Autowired+@Qualifier 执行逻辑(先型后名,型为基础、名为筛选)
三、一句话核心区分
- @Resource:先锁定 Bean 名称,再验证类型;名称找不到才按类型找;
- @Autowired+@Qualifier:先锁定类型范围,再在范围内找指定名称的 Bean。
三、核心对比与选型建议
| @Primary | Spring | 类型匹配 + 默认首选 | 实现类端 | 低 | ⭐⭐⭐ |
| @Qualifier | Spring | 类型 + 名称精准匹配 | 注入端 | 高 | ⭐⭐⭐⭐⭐ |
| @Resource | JDK 原生 | 直接按名称匹配 | 注入端 | 中 | ⭐⭐⭐⭐ |





