Spring Boot
Profile
文件结构:
src/main/resources/
├── application.yml
├── application-dev.yml
└── application-prod.ymlapplication.yml放公共配置:
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直接暴露给前端,里面可能包含密码、敏感字段、
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的部分字段
- 扁平化、无业务逻辑、无敏感字段。通常用于接受前端传来的参数(如注册请求)
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对象
@PostMapping
public void add(@RequestBody DishDTO dishDTO) {
}@RequestParam
接受查询参数,/user?id=10
@GetMapping("/user")
public User get(@RequestParam Long id) {
}这样写默认id是必传的,如果要可选的话
@GetMapping("/user")
public User get(@RequestParam(required = false) Long id) {
}@PathVariable
接受路径参数,/user/10
@GetMapping("/user/{id}")
public User get(@PathVariable Long id) {
}@Mapper
告诉MyBatis,这个接口是Mapper,让MyBatis为它创建实现类,并交给Spring使用
在项目里只写了接口没有写实现类
@Mapper
public interface UserMapper {
User getById(Long id);
}但是在Service的实现类可以直接注入
UserMapper 接口
↓
MyBatis 扫描到 @Mapper
↓
创建 Mapper 代理对象
↓
注册到 Spring 容器
↓
@Resource / @Autowired
↓
Service 获取 UserMapper@MapperScan
如果你的Mapper很多,每个接口上都要加上@Mapper
在启动类上加上
@SpringBootApplication
@MapperScan("com.sky.mapper")
public class SkyApplication {
}MyBatis就会扫描com.sky.mapper下的所有接口
@RequestMapping
@RestController
@RequestMapping("/admin/user")
public class UserController {
}表示这个Controller下面的接口都以/admin/user开头,比如@GetMapping("/page"),最终接口长/admin/user/page
@Service
用来标记一个类是“业务层组件”,让Spring自动创建并管理这个类的对象
@Service
public class DishServiceImpl implements DishService {
}Spring启动时发现这个注解,就会把DishServiceImpl创建成一个Bean,放进Spring容器,这样在Controller层才能通过@Autowired注入
@Resource
@Resource用来让Spring自动把一个对象注入到你的类中
如果不用注解,那就创建一个
RedisService redisService = new RedisService();但是不推荐这么干,它应该有Spring负责创建和管理
启动Spring Boot
↓
扫描 @Component / @Service / @Repository / @Controller
↓
创建对象
↓
放入Spring容器@Bean
把一个自己创建的对象交给Spring容器管理
@Bean
↓
把对象放进 Spring 容器
@Resource / @Autowired
↓
从 Spring 容器取对象为什么需要@Bean,比如
@Configuration
public class Config {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}是第三方库/框架类,你不能或没必要去他源码上加@Component,直接用@Bean
@Controller
主要用于返回页面
@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
需要显示引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>本身不是校验规则,真正规则来自@NotNull、@NotBlank、@Size、@Email等注解约束
常见用法
@PostMapping("/users")
public User create(@Valid @RequestBody UserDTO user) {
// 如果校验失败,默认抛出 MethodArgumentNotValidException,返回 400
return userService.create(user);
}UserDTO里写约束:
public class UserDTO {
@NotBlank(message = "姓名不能为空")
private String name;
@Email(message = "邮箱格式不正确")
private String email;
@Valid // 级联校验:AddressDTO 内部的约束也会生效
private AddressDTO address;
}如果希望自己处理错误,可以在@Valid参数后面紧跟BindingResult:
@PostMapping("/users")
public Result create(@Valid @RequestBody UserDTO user, BindingResult result) {
if (result.hasErrors()) {
// 自定义错误处理
}
return Result.ok();
}级联校验
嵌套对象必须加@Valid,否则只校验外层对象,不校验内层:
public class OrderDTO {
@Valid
private UserDTO user; // 不加 @Valid,UserDTO 里的约束不会触发
}方法级校验
如果要在 Service 或 Controller 的普通方法参数上直接校验,例如 @PathVariable、@RequestParam,通常需要:
类上加
@Validated参数上加约束注解,或
@Validjava@Validated @RestController public class UserController { @GetMapping("/users/{id}") public User get(@PathVariable @Min(1) Long id) { // id < 1 时抛 ConstraintViolationException return userService.get(id); } }