笔记参考于柏码知识库
SpringBoot简化了配置过程,只需导入相应启动器(starter)依赖。
基础
创建项目
在官网少量配置就能快速生成SpringBoot模板:https://start.spring.io/
并且IDEA已经将此工具集成到了内部,创建项目选择Spring Initializr类型,之后选择模块。
常用模块快速整合
导入依赖,无需配置就可以正常使用:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
SpringBoot支持自动包扫描, 不需要配置,在主类所在包内任意路径创建组件都可以生效。
对象也可以直接以JSON形式返回客户端,SpringBoot官方默认使用的是Jackson和Gson的HttpMessageConverter来进行配置:
1 2 3 4 5 6 7 8 9
| @ResponseBody @GetMapping("/") public Student index(){ Student student = new Student(); student.setName("小明"); student.setSex("男"); student.setSid(10); return student; }
|
添加WebMvc类:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration public class WebConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return HandlerInterceptor.super.preHandle(request, response, handler); } }); } }
|
导入SpringSecurity框架即可生效,并设置了一个用户,用户名为user,密码为随机密码:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
|
额外配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Configuration public class SecurityConfiguration {
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(auth -> { auth.anyRequest().authenticated(); }) .formLogin(conf -> { conf.loginPage("/login"); conf.loginProcessingUrl("/doLogin"); conf.defaultSuccessUrl("/"); conf.permitAll(); }) .build(); } }
|
自定义运行器
编写自定义的ApplicationRunner,在项目启动完成时执行:
1 2 3 4 5 6 7
| @Component public class TestRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("我是自定义执行!"); } }
|
配置文件
在application.properties中进行配置编写。
可以使用@Value来访问配置文件中的值:
1 2 3 4 5
| @Controller public class TestController { @Value("${test.data}") int data; }
|
可以将配置文件后缀修改为yml或yaml,来使用对应格式编写。如数据源配置:
1 2 3 4 5 6
| spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
|
对于@Mapper文件,只需要在对应接口添加@Mapper注解,或在配置类上添加@MapperScan即可(二选一)。
SpringSecurity与SpringBootMvc配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| spring: mvc: static-path-pattern: /static/** security: filter: order: -100 user: name: 'admin' password: '123456' roles: - admin - user
|
打包
可以一键打包为jar,然后一行命令运行:
1
| java -jar demo-0.0.1-SNAPSHOT.jar
|
还可以直接编译为操作系统原生程序,需要使用GraalVM环境。但Mybatis目前不支持Native-Image。
日志系统
日志门面和日志实现
日志门面(Facade),如SlF4j相当于一种规范,只提供统一的日志使用接口。而起具体实现便是日志实现。
SpringBoot为了统一日志框架的使用,进行了以下处理:
- 直接将其他依赖以前的日志框架剔除
- 导入对应日志框架的Slf4j中间包
- 导入自己官方指定的日志实现,并作为Slf4j的日志实现层
打印项目日志信息
SpringBoot使用的是Slf4j作为日志门面,Logback作为日志实现,对应的依赖为:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency>
|
在使用Lombok后,添加@Slf4j注解即可直接打印信息:
1 2 3 4 5 6 7 8 9 10 11 12
| @Slf4j @Controller public class MainController {
@ResponseBody @GetMapping("/test") public User test(){ log.info("用户访问了一次测试数据"); return mapper.findUserById(1); } ...
|
日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,默认只会打印INFO以上级别的信息。
多环境配置
可以通过配置文件指定,并创建类似application-dev.yml和application-prod.yml的配置文件:
1 2 3
| spring: profiles: active: dev
|
打包时,可以通过Maven配置多环境:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <environment>dev</environment> </properties> </profile> <profile> <id>prod</id> <activation> <activeByDefault>false</activeByDefault> </activation> <properties> <environment>prod</environment> </properties> </profile> </profiles>
|
排除其他环境的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <resources>
<resource> <directory>src/main/resources</directory> <excludes> <exclude>application*.yml</exclude> </excludes> </resource>
<resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>application.yml</include> <include>application-${environment}.yml</include> </includes> </resource> </resources>
|
之后可以将Maven的environment属性传递给SpringBoot配置文件:
1 2 3
| spring: profiles: active: '@environment@'
|
其他常用框架
邮件发送模块
导入封装好的邮件模块:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
|
配置smtp服务器:
1 2 3 4 5 6 7 8
| spring: mail: host: smtp.163.com username: javastudy111@163.com password: AZJTOAWZESLMHTNI
|
使用SimpleMailMessage发送简单邮件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @SpringBootTest class SpringBootTestApplicationTests {
@Autowired JavaMailSender sender;
@Test void contextLoads() { SimpleMailMessage message = new SimpleMailMessage(); message.setSubject("【电子科技大学教务处】关于近期学校对您的处分决定"); message.setText("XXX同学您好,经监控和教务巡查发现,您近期存在旷课、迟到、早退、上课刷抖音行为," + "现已通知相关辅导员,请手写5000字书面检讨,并在2022年4月1日17点前交到辅导员办公室。"); message.setTo("你的QQ号@qq.com"); message.setFrom("javastudy111@163.com"); sender.send(message); }
}
|
使用MimeMessageHelper实现添加附件等更多功能:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Test void contextLoads() throws MessagingException { MimeMessage message = sender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setSubject("Test"); helper.setText("lbwnb"); helper.setTo("你的QQ号@qq.com"); helper.setFrom("javastudy111@163.com"); sender.send(message); }
|
接口规则校验
导入接口校验框架:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
|
使用注解实现接口校验:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Slf4j @Validated @Controller public class TestController {
...
@ResponseBody @PostMapping("/submit") public String submit(@Length(min = 3) String username, //使用@Length注解一步到位 @Length(min = 10) String password){ System.out.println(username.substring(3)); System.out.println(password.substring(2, 10)); return "请求成功!"; } }
|
处理异常:
1 2 3 4 5 6 7 8 9
| @ControllerAdvice public class ValidationController {
@ResponseBody @ExceptionHandler(ConstraintViolationException.class) public String error(ValidationException e){ return e.getMessage(); } }
|
对于对象类型:
1 2 3 4 5 6 7
| @Data public class Account { @Length(min = 3) String username; @Length(min = 10) String password; }
|
1 2 3 4 5 6 7
| @ResponseBody @PostMapping("/submit") public String submit(@Valid Account account){ System.out.println(account.getUsername().substring(3)); System.out.println(account.getPassword().substring(2, 10)); return "请求成功!"; }
|
异常处理:
1 2 3 4 5 6 7 8 9 10 11
| @ResponseBody @ExceptionHandler({ConstraintViolationException.class, MethodArgumentNotValidException.class}) public String error(Exception e){ if(e instanceof ConstraintViolationException exception) { return exception.getMessage(); } else if(e instanceof MethodArgumentNotValidException exception){ if (exception.getFieldError() == null) return "未知错误"; return exception.getFieldError().getDefaultMessage(); } return "未知错误"; }
|
接口文档生成
使用Swagger,导入依赖:
1 2 3 4 5
| <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.1.0</version> </dependency>
|
配置文档描述信息:
1 2 3 4 5 6 7 8 9
| @Bean public OpenAPI springDocOpenAPI() { return new OpenAPI().info(new Info() .title("图书管理系统 - 在线API接口文档") .description("这是一个图书管理系统的后端API文档,欢迎前端人员查阅!") .version("2.0") .license(new License().name("我的B站个人主页") .url("https://space.bilibili.com/37737161"))); }
|
为Controller编写API信息:
1 2 3 4 5
| @Tag(name = "账户验证相关", description = "包括用户登录、注册、验证码请求等操作。") public class TestController { ... }
|
添加请求映射配置描述信息:
1 2 3 4 5 6 7 8 9 10 11
| @ApiResponses({ @ApiResponse(responseCode = "200", description = "测试成功"), @ApiResponse(responseCode = "500", description = "测试失败") //不同返回状态码描述 }) @Operation(summary = "请求用户数据测试接口") @ResponseBody @GetMapping("/hello")
public String hello(@Parameter(description = "测试文本数据", example = "KFCvivo50") @RequestParam String text) { return "Hello World"; }
|
隐藏接口:
1 2 3 4 5 6
| @Hidden @ResponseBody @GetMapping("/hello") public String hello() { return "Hello World"; }
|
实体类文档:
1 2 3 4 5 6 7 8 9 10 11 12
| @Data @Schema(description = "用户信息实体类") public class User { @Schema(description = "用户编号") int id; @Schema(description = "用户名称") String name; @Schema(description = "用户邮箱") String email; @Schema(description = "用户密码") String password; }
|
在生成环境关闭文档:
1 2 3
| springdoc: api-docs: enabled: false
|