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 注解的作用:

  1. 将 Controller 方法的返回值直接写入 HTTP 响应体
  2. 如果返回值是对象或集合,SpringMVC 会自动将数据转换为 JSON 再响应
  3. @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;
  }
}

第二章 分层解耦

一、三层架构

  1. 控制层 (Controller): 接收前端发送的请求,对请求进行处理,并响应数据。
  2. 业务逻辑层 (Service): 处理具体的业务逻辑。
  3. 数据访问层 (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 规范提供
默认按类型注入 默认按名称注入
posted @ 2026-04-05 13:43  fallw  阅读(3)  评论(0)    收藏  举报