JavaWeb 笔记 04 (46 - 49)
SpringBootWeb 案例, 分层解耦相关 (46 - 49)
提前声明:本文章仅作个人学习记录,不涉及商业用途。
内容记录于学习途中, 没有按分类进行总结, 可能存在错误或不完整之处。
第一章 SpringBootWeb 案例
1. 常用依赖
启动依赖
Developer Tools -> Lombok
// 自动生成 Getter / Setter 与构造函数
Developer Tools -> Spring Boot DevTools
// 提供代码热重启与浏览器实时重载
Developer Tools -> Spring Configuration Processor
// 为自定义配置属性提供 IDE 自动补全提示
Web -> Spring Web
// 构建 RESTful 及 MVC 网络服务
SQL -> JDBC API
// 连接数据库并执行 SQL 语句
SQL -> MyBatis Framework
// 支持自定义 SQL、存储过程的持久层框架
dependency
<!-- JSON 对象转换 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.40</version>
</dependency>
<!-- MySQL JDBC driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>6.0.3</version>
<scope>test</scope>
</dependency>
<!-- 阿里云OSS Java SDK V2 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibabacloud-oss-v2</artifactId>
<version>0.3.2</version>
</dependency>
<!-- Apache Commons CLI -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.11.0</version>
<scope>compile</scope>
</dependency>
<!-- knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
plugin
<!-- 显式声明 mockito-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar
</argLine>
</configuration>
</plugin>
<plugin>
3. 配置文件
spring:
application:
name: tlias-dev
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tlias
username: fallw
password: real-password
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
mapper-locations: classpath*:mapper/*.xml
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: real-bucket-name
region: cn-beijing
2. 入门案例
静态资源存放位置:src/main/resources/static
@ResponseBody 注解的作用:
- 将 Controller 方法的返回值直接写入 HTTP 响应体
- 如果返回值是对象或集合,SpringMVC 会自动将数据转换为 JSON 再响应
@RestController=@Controller+@ResponseBody
// RestController 将对象/集合 -> JSON -> 响应体
@RestController
public class UserController {
@RequestMapping("/list")
public List<User> list() throws Exception {
// 1. 数据访问:获取用户数据
InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
ArrayList<String> lines = IoUtils.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());
// 2. 逻辑处理:解析数据、封装成对象
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());
// 3. 接收请求、响应数据
return userList;
}
}
第二章 分层解耦
一、三层架构
- 控制层 (Controller): 接收前端发送的请求,对请求进行处理,并响应数据。
- 业务逻辑层 (Service): 处理具体的业务逻辑。
- 数据访问层 (Data Acess Object): 持久层,负责数据库访问操作。
二、分层解耦
耦合:衡量软件中各个层 / 模块之间的依赖关联程度。
内聚:软件中各个模块内部的功能关系。
软件设计原则:高内聚低耦合。
0. 实体类 POJO
// pojo.User.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private String name;
private Integer age;
}
1. Controller 层
// controller.UserController.java
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@RequestMapping("/users")
public List<User> list() {
return userService.findAll();
}
}
2. Service 层
接口
// service.UserService.java
public interface UserService {
public List<User> findAll();
}
实现类
// service.impl.UserServiceImpl.java
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Override
public List<User> findAll() {
return userMapper.findAll();
}
}
3. Mapper 层
// mapper.UserMapper.java
@Mapper
public interface UserMapper {
@Select("select * from user")
public List<User> findAll();
@Insert("insert into user(username, password, name, age) values(#{username}, #{password}, #{name}, #{age})")
public void insert(User user);
@Update("update user set username = #{username}, password = #{password}, name = #{name}, age = #{age} where id = #{id}")
public void update(User user);
@Delete("delete from user where id = #{id}")
public void delete(Integer id);
}
三、IOC & DI
IOC (Inversion of Control): 控制反转,对象的控制权由程序自身转移到外部(容器)。
DI (Dependency Injection): 依赖注入,容器为应用程序提供运行时,所依赖的资源。
Bean 对象:IOC 容器中创建、管理的对象。
1. Bean 对象定义 Bean Definition (IOC)
| 注解 | 说明 | 位置 |
|---|---|---|
@Component |
声明 bean 的基础注解 | 不属于以下三类时,用此注解 使用 @Component(value = "userMapper") 指定 bean 的名称 |
@Controller |
@Component 的衍生注解 |
标注在控制层类上 声明控制器只能用 @Controlller |
@RestController |
控制层常用注解 | @Controller + @ResponseBody |
@Service |
@Component 的衍生注解 |
标注在业务层类上 |
@Repository |
@Component 的衍生注解 |
标注在数据访问层类上 由于与 Mybatis 整合,用的少 |
@Mapper |
MyBatis 提供的持久层注解 | 标注在 Mapper 接口上 由 MyBatis 框架提供,非 Spring 原生 |
@ComponentScan |
组件扫描注解 | @SpringBootApplication 默认扫描范围是启动类所在包 (com.fallw) 及子包 |
2. 依赖注入 Dependency Injection (DI)
推荐使用 @RequiredArgsConstructor
// @RequiredArgsConstructor: 自动为所有标注为 final 的字段生成构造函数
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
...
}
属性注入 @Autowired
@Service
public class UserServiceImpl implements UserService {
// @Autowied: Spring 自动从容器中查找并注入
@Autowired
private UserMapper userMapper;
...
}
构造器注入
@Service
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
// Spring 4.x 后,如果只有一个构造函数,@Autowired 可省略
@Autowired
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
...
}
setter 注入
@Service
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
@Autowired
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
...
}
3. 重复注入处理
@Autowired 默认按类型注入,找不到再按名称注入。
@Primary
// @Primary 指定优先注入对象
@Primary
@Service
public class UserServiceImpl implements UserService {
...
}
@Autowird + @Qualifier
@Service
public class UserServiceImpl implements UserService {
// @Qualifier 指定注入对象名称
@Qualifier("userMapper")
@Autowired
private UserMapper userMapper;
...
}
@Resource
@Service
public class UserServiceImpl implements UserService {
// @Resource 指定注入对象名称
@Resource(name = "userMapper")
private UserMapper userMapper;
...
}
@Autowired |
@Resource |
|---|---|
| Spring 框架提供 | Java EE 规范提供 |
| 默认按类型注入 | 默认按名称注入 |
浙公网安备 33010602011771号