目录
三、如何在 springboot 中使用 IoC 和 DI?
一、什么是控制反转(IoC)?
控制反转(Inversion of Control,简称 IoC)是一种设计原则,它的目的是降低代码之间的耦合度,提高模块化和可测试性。控制反转的含义是,将对象的创建、配置和管理交给一个外部容器来完成,而不是由对象自己或使用对象的类来完成。这样,对象就不需要知道或关心它们的依赖关系是如何被创建和维护的,只需要按照一定的规则和接口与容器进行交互即可。
在 spring 框架中,IoC 容器就是负责实现控制反转的核心组件,它可以通过配置文件或注解的方式来管理应用程序中的各种 bean(即被容器管理的对象)。IoC 容器可以根据 bean 的定义和依赖关系来自动创建、装配和销毁 bean,从而简化了开发者的工作。
二、什么是依赖注入(DI)?
依赖注入(Dependency Injection,简称 DI)是一种实现控制反转的具体方法,它的思想是,当一个对象需要另一个对象(或多个对象)来完成某些功能时,不是由该对象自己去创建或查找依赖对象,而是由外部容器在运行时将依赖对象通过构造器、方法或属性等方式注入到该对象中。这样,对象就可以在不改变自身代码的情况下,动态地获得所需的依赖对象,并且可以方便地替换不同的实现。
在 spring 框架中,DI 是通过 IoC 容器来实现的,开发者只需要在 bean 的定义中声明其依赖关系,或者在 bean 的类中使用注解来标注其依赖属性或方法,就可以让 IoC 容器自动地为其注入相应的 bean。spring 支持基于类型(by type)、基于名称(by name)和基于构造器(by constructor)等多种方式来进行依赖注入。
三、如何在 springboot 中使用 IoC 和 DI?
springboot 是一种基于 spring 的轻量级框架,它可以帮助开发者快速搭建和运行 spring 应用程序,无需过多的配置和代码。springboot 采用了约定优于配置(convention over configuration)的原则,提供了一系列的自动配置类和启动器(starter),使得开发者只需要引入相应的依赖,并按照一定的规范来编写代码,就可以让 springboot 为其自动配置好所需的 bean 和组件。
要在 springboot 中使用 IoC 和 DI,有以下几个步骤:
- 在 pom.xml 文件中引入 spring-boot-starter-web 依赖,这会自动引入 spring-webmvc、spring-aop、spring-beans 等与 web 开发相关的组件。
- 在主类上使用 @SpringBootApplication 注解,这会启用自动配置、组件扫描和其他特性。
- 在需要被 IoC 容器管理的类上使用 @Component、@Service、@Controller、@Repository 等注解,这会让 springboot 自动扫描并注册这些类为 bean。
- 在需要依赖注入的类中使用 @Autowired、@Resource、@Inject 等注解,或者使用构造器或 setter 方法,来标注或声明其依赖的 bean,这会让 springboot 自动为其注入相应的 bean 实例。
- 在 application.properties 或 application.yml 文件中配置一些自定义的属性或参数,这会覆盖 springboot 的默认配置,并且可以在 bean 中使用 @Value 或 @ConfigurationProperties 注解来获取这些属性的值。
下面是一个简单的示例,演示了如何在 springboot 中使用 IoC 和 DI 来实现一个用户服务的功能:
// User.java
package com.example.demo.entity;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
}
// UserDao.java
package com.example.demo.dao;
import com.example.demo.entity.User;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Repository
public class UserDao {
// 模拟数据库
private static final List<User> users = new ArrayList<>();
static {
users.add(new User(1L, "Alice", 20));
users.add(new User(2L, "Bob", 21));
users.add(new User(3L, "Charlie", 22));
}
// 根据 id 查询用户
public User findById(Long id) {
Optional<User> user = users.stream().filter(u -> u.getId().equals(id)).findFirst();
return user.orElse(null);
}
// 查询所有用户
public List<User> findAll() {
return users;
}
}
// UserService.java
package com.example.demo.service;
import com.example.demo.dao.UserDao;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
// 注入 UserDao
@Autowired
private UserDao userDao;
// 根据 id 查询用户
public User getUserById(Long id) {
return userDao.findById(id);
}
// 查询所有用户
public List<User> getAllUsers() {
return userDao.findAll();
}
}
// UserController.java
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
// 注入 UserService
@Autowired
private UserService userService;
// 根据 id 查询用户
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
// 查询所有用户
@GetMapping("/users")
public List<User> getUsers() {
return userService.getAllUsers();
}
}
// DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
总结
控制反转和依赖注入是 spring 框架的核心特征,它们可以帮助开发者编写出低耦合、高内聚、易测试的代码,提高开发效率和质量。springboot 是一种基于 spring 的轻量级框架,它可以让开发者更方便地使用 spring 的功能,无需过多的配置和代码。要在 springboot 中使用 IoC 和 DI,只需要引入相应的依赖,使用一些简单的注解,就可以实现对象的创建、配置和管理。