为什么要采用三层架构?

在 service 和 dao 层中,通常会先定义接口(命名规范为对象名+Service/Dao),再用实现类(命名规范为接口名+Impl)去实现接口,最后通过调用方法进行业务设计。

Spring 框架为更好地标识 bean 所属层次,提供了 @Component 及其衍生注解:
注解 | 说明 | 位置 |
|---|---|---|
@Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 |
@Controller | @Component的衍生注解 | 标注在控制层类上 |
@Service | @Component的衍生注解 | 标注在业务层类上 |
@Repository | @Component的衍生注解 | 标注在数据访问层类上(由于与mybatis整合,用的少) |
示例:
Service 层
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findAll(){
List<String> lines = userDao.findAll();
List<User> users = lines.stream().map(line -> {
String[] s1 = line.split(",");
String ID = s1[0];
String username = s1[1];
Integer password = Integer.parseInt(s1[2]);
String name= s1[3];
Integer age = Integer.parseInt(s1[4]);
LocalDateTime updateTime = LocalDateTime.parse(s1[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return new User(ID,username,password,name,age,updateTime);
}).collect(Collectors.toList());
return users;
}
}Dao 层
@Repository
public class UserDaoImpl implements UserDao {
@Override
public List<String> findAll() {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("user.txt");
ArrayList<String> lines = IoUtil.readLines(resourceAsStream, StandardCharsets.UTF_8, new ArrayList<>());
return lines;
}
}注意:
属性注入
@Autowired
private UserService userService;构造函数注入
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}Setter方法注入
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}@Primary :指定默认实现
@Primary
@Service
public class UserServiceImpl implements UserService {}@Qualifier :指定注入的 bean 名称,需配合 @Autowired
@Qualifier("userServiceImpl")
@Autowired
private UserService userService;@Resource :按 bean 名称注入
@Resource(name = "userServiceImpl")
private UserService userService;