Skip to content

Spring Boot ​

Profile ​

文件结构:

src/main/resources/
├── application.yml
├── application-dev.yml
└── application-prod.yml

application.yml放公共配置:

yaml
spring:
  profiles:
    active: dev

使用dev环境,Spring Boot就会加载

application.yml
        +
application-dev.yml

数据模型 ​

Entity(实体)、DTO(数据传输对象)、VO(视图对象)

Entity管数据库,DTO管传输、VO管前端展示

Entity ​

  • 定位:数据库映射层
  • 职责:与数据库表结构一一对应(通常用JPA/Hibernate的@Entity或Mybatis的resultMap映射)
  • 特点:包含数据库字段、关联关系(如@OneToMany)和审计字段(如createTime,updateTime)
  • 注意:不要将Entity直接暴露给前端,里面可能包含密码、敏感字段、
java
import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "user")
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password; // 敏感字段!绝不能传到前端
    private String email;
    private LocalDateTime createTime;
    // getter/setter...
}

DTO ​

  • 定位:业务传输层
  • 职责:为了减少网络传输开销和解耦内部实体,它聚会了多个Entity的数据,或者只提取Entity的部分字段
  • 扁平化、无业务逻辑、无敏感字段。通常用于接受前端传来的参数(如注册请求)
java
import javax.validation.constraints.NotBlank;

// 接收前端注册请求的 DTO
public class UserRegisterDTO {
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @NotBlank(message = "密码不能为空")
    private String password; // 注意:接收时可以存在,但返回时必须脱敏
    private String email;
    // getter/setter...
}

VO ​

  • 定位:视图展示层(专门返回给前端页面)
  • 职责:根据前端具体的 UI 需求,定制化展示数据。比如前端需要显示 年龄,但数据库存的是 出生日期,VO 可以把日期计算成年龄再返回。
  • 特点:面向 UI 展示,可以额外增加前端专属字段(如 listIndex, totalPages),不包含任何业务逻辑。

注解 ​

@RestController ​

专门用来写REST API接口的Controller,把方法的返回值直接作为HTTP响应数据返回,相当于@Controller 加@ResponseBody

@RequestBody ​

把HTTP请求体(Request Body)中的JSON数据,转换成Java对象

java
@PostMapping
public void add(@RequestBody DishDTO dishDTO) {

}

@RequestParam ​

接受查询参数,/user?id=10

java
@GetMapping("/user")
public User get(@RequestParam Long id) {
}

这样写默认id是必传的,如果要可选的话

java
@GetMapping("/user")
public User get(@RequestParam(required = false) Long id) {
}

@PathVariable ​

接受路径参数,/user/10

java
@GetMapping("/user/{id}")
public User get(@PathVariable Long id) {
}

@Mapper ​

告诉MyBatis,这个接口是Mapper,让MyBatis为它创建实现类,并交给Spring使用

在项目里只写了接口没有写实现类

java
@Mapper
public interface UserMapper {

    User getById(Long id);

}

但是在Service的实现类可以直接注入

UserMapper 接口
      ↓
MyBatis 扫描到 @Mapper
      ↓
创建 Mapper 代理对象
      ↓
注册到 Spring 容器
      ↓
@Resource / @Autowired
      ↓
Service 获取 UserMapper

@MapperScan ​

如果你的Mapper很多,每个接口上都要加上@Mapper

在启动类上加上

java
@SpringBootApplication
@MapperScan("com.sky.mapper")
public class SkyApplication {
}

MyBatis就会扫描com.sky.mapper下的所有接口

@RequestMapping ​

java
@RestController
@RequestMapping("/admin/user")
public class UserController {
}

表示这个Controller下面的接口都以/admin/user开头,比如@GetMapping("/page"),最终接口长/admin/user/page

@Service ​

用来标记一个类是“业务层组件”,让Spring自动创建并管理这个类的对象

java
@Service
public class DishServiceImpl implements DishService {

}

Spring启动时发现这个注解,就会把DishServiceImpl创建成一个Bean,放进Spring容器,这样在Controller层才能通过@Autowired注入

@Resource ​

@Resource用来让Spring自动把一个对象注入到你的类中

如果不用注解,那就创建一个

java
RedisService redisService = new RedisService();

但是不推荐这么干,它应该有Spring负责创建和管理

java
启动Spring Boot
      ↓
扫描 @Component / @Service / @Repository / @Controller
      ↓
创建对象
      ↓
放入Spring容器

@Bean ​

把一个自己创建的对象交给Spring容器管理

java
@Bean
 ↓
把对象放进 Spring 容器

@Resource / @Autowired
 ↓
从 Spring 容器取对象

为什么需要@Bean,比如

java
@Configuration
public class Config {

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

是第三方库/框架类,你不能或没必要去他源码上加@Component,直接用@Bean

@Controller ​

主要用于返回页面

java
@Controller
public class UserController {

    @GetMapping("/user")
    public String user() {
        return "user";
    }
}

这里的return "user",可能表示:template/user.html

@Configuration ​

告诉Spring,这个类是配置类,里面的可以定义交给Spring的Bean

@Component ​

告诉Spring,把这个类创建成对象,并交给IoC容器管理

@RestControllerAdvice ​

本质上@ControllerAdvice和@ResponseBody的组合注解

  • @ControllerAdvice:把类变成全局控制器增强,能拦截所有(或指定范围)的Controller
  • @ResponseBody:类中所有方法的返回值都自动序列化成JSON/XML,写入响应体

所以最常用于:全局异常处理,统一返回json错误信息

@Valid ​

需要显示引入

java
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

本身不是校验规则,真正规则来自@NotNull、@NotBlank、@Size、@Email等注解约束

常见用法

java
@PostMapping("/users")
public User create(@Valid @RequestBody UserDTO user) {
    // 如果校验失败,默认抛出 MethodArgumentNotValidException,返回 400
    return userService.create(user);
}

UserDTO里写约束:

java
public class UserDTO {
    @NotBlank(message = "姓名不能为空")
    private String name;

    @Email(message = "邮箱格式不正确")
    private String email;

    @Valid // 级联校验:AddressDTO 内部的约束也会生效
    private AddressDTO address;
}

如果希望自己处理错误,可以在@Valid参数后面紧跟BindingResult:

java
@PostMapping("/users")
public Result create(@Valid @RequestBody UserDTO user, BindingResult result) {
    if (result.hasErrors()) {
        // 自定义错误处理
    }
    return Result.ok();
}

级联校验 ​

嵌套对象必须加@Valid,否则只校验外层对象,不校验内层:

java
public class OrderDTO {
    @Valid
    private UserDTO user; // 不加 @Valid,UserDTO 里的约束不会触发
}

方法级校验 ​

如果要在 Service 或 Controller 的普通方法参数上直接校验,例如 @PathVariable、@RequestParam,通常需要:

  • 类上加 @Validated

  • 参数上加约束注解,或 @Valid

    java
    @Validated
    @RestController
    public class UserController {
    
        @GetMapping("/users/{id}")
        public User get(@PathVariable @Min(1) Long id) {
            // id < 1 时抛 ConstraintViolationException
            return userService.get(id);
        }
    }