理解IOC控制反转,具体的应用场景,就是在学spring boot 的学生信息管理系统的时候,什么时候会用到注入,就是在service层 对studentservive 的接口的实现类上会用到调用repository的接口的实现类的实例化对象,这个部分是spring 的JPA自动给你完成的(动态代理),而这个对象是存在spring 这个容器里的
所以spring可以看成一个存放实例对象的容器
如何理解IOC 就是控制反转,也就是以前你来掌控着这个对象的创建,现在不用你创建了,你给这个控制的权力交给了spring
是不是只要用到接口,就得用 @Autowired?
基本可以这么理解,但有一个前提条件: 这个接口的实现类必须已经被 Spring **"托管"**了。
- 前提条件 :你在
StudentServiceImpl类上加了@Service注解。 - 执行逻辑 :
- Spring 启动时,看到
@Service,于是把StudentServiceImpl实例化并放进"容器"里。 - Spring 扫描到
Controller里的@Autowired,它会去容器里找:"谁实现了StudentService这个接口?" - 找到了!然后把那个实例"注入"到
studentService变量中。
- Spring 启动时,看到
结论: 只要你想利用 Spring 容器里现成的对象(Bean),你就得用
@Autowired。如果你自己去new StudentServiceImpl(),那这个对象就不受 Spring 管理了(比如它里面的 Repository 也会失效)。
完整的"层级调用链"
我们可以把这三层连起来看,你会发现每一层都在用 @Autowired 向上"借力":
-
Repository 层:直接操作数据库。
-
Service 层 :
java@Autowired private StudentRepository studentRepository; // 注入 Repository -
Controller 层 :
java@Autowired private StudentService studentService; // 注入 Service
为什么不直接在 Controller 里注入 Repository?
你可能会想:"既然 Repository 就能查数据库,为什么还要多此一举经过 Service 层呢?"
这是一个代码整洁度的问题:
- 直接调用(偷懒法):Controller -> Repository。如果只是简单的查个表,确实没问题。
- 标准调用(专业法) :Controller -> Service -> Repository。
- 原因 :如果有一天,"删除学生"这个功能变得复杂了(比如:删除后要给家长发短信,还要更新班级人数),这些复杂的代码应该写在 Service 里。Controller 永远只需要喊一句
studentService.deleteById(id)即可,它不需要知道背后发生了多少复杂的事情。
- 原因 :如果有一天,"删除学生"这个功能变得复杂了(比如:删除后要给家长发短信,还要更新班级人数),这些复杂的代码应该写在 Service 里。Controller 永远只需要喊一句
总结
@Autowired 就像是**"拼插积木"**的接口。
- 你在 Service 上留个插口(
@Service)。 - 你在 Controller 上用磁铁吸住它(
@Autowired)。
这样,整个系统的各个零件就紧密地结合在一起了。
**这就是 Spring 的依赖注入(DI)。