解耦-IOCDI
文章目录
- 解耦思路
- IOC详解
- Service层:
- Dio层:
- 组件扫描
- DI详解
- 多个相同类型的bean对象
解耦思路
- 提供一个容器,容器中存储一些对象(例:UserService对象)
- Controller程序从容器中获取UserService类型的对象
在实现类加上 @Component 注解,就代表把当前类产生的对象交给IOC容器管理。
实例化对象时,加上@Autowired注解,自动查询该类型的bean对象,并赋值给该成员变量
package com.example.service.impl;import com.example.Dao.UserDao;
import com.example.Dao.impl.UserDaoImpl;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;@Component //将当前类交给IOC容器管理
public class UserServiceImpl implements UserService {@Autowired //应用程序运行时,自动查询该类型的bean对象,并赋值给该成员变量private UserDao userDao;@Overridepublic List<User> findAll() {//调用Dao获取数据List<String> lines = userDao.findAll();//解析用户信息,封装List<User> userList = lines.stream().map(line -> {String[] parts = line.split(",");Integer id = Integer.parseInt(parts[0]);String username = parts[1];String password = parts[2];String name = parts[3];Integer age = Integer.parseInt(parts[4]);LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id, username, password, name, age, updateTime);}).toList();//返回return userList;}
}
IOC详解
Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了@Component的衍生注解:
可以使用 @Service 注解声明Service层的bean。 使用 @Repository 注解声明Dao层的bean。
Service层:
@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic List<User> findAll() {List<String> lines = userDao.findAll();List<User> userList = lines.stream().map(line -> {String[] parts = line.split(",");Integer id = Integer.parseInt(parts[0]);String username = parts[1];String password = parts[2];String name = parts[3];Integer age = Integer.parseInt(parts[4]);LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id, username, password, name, age, updateTime);}).collect(Collectors.toList());return userList;}
}
Dio层:
@Repository
public class UserDaoImpl implements UserDao {@Overridepublic List<String> findAll() {InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");ArrayList<String> lines = IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());return lines;}
}
组件扫描
- 前面声明bean的四大注解,要想生效,还需要被组件扫描注解 @ComponentScan 扫描。
- 该注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。
DI详解
@Autowired注解,默认是按照类型进行自动装配的(去IOC容器中找某个类型的对象,然后完成注入操作)
@Autowired用法
- 属性注入
@RestController
public class UserController {//方式一: 属性注入@Autowiredprivate UserService userService;}
- 构造函数注入
@RestController
public class UserController {//方式二: 构造器注入private final UserService userService;@Autowired //如果当前类中只存在一个构造函数, @Autowired可以省略public UserController(UserService userService) {this.userService = userService;}}
- setter注入
/*** 用户信息Controller*/
@RestController
public class UserController {//方式三: setter注入private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}
}
多个相同类型的bean对象
- 使用@Primary注解
@Primary
@Service
public class UserServiceImpl implements UserService {
}
- 使用@Qualifier注解
@RestController
public class UserController {@Qualifier("userServiceImpl")@Autowiredprivate UserService userService;
- 使用@Resource注解
@RestController
public class UserController {@Resource(name = "userServiceImpl")private UserService userService;