面试官最喜欢问的 Spring Boot 知识点整理【附解答】(下)
import java.util.List;
@Component
@ConfigurationProperties(prefix = "library")
@Setter
@Getter
@ToString
class LibraryProperties {
private String location;
private List<Book> books;
@Setter
@Getter
@ToString
static class Book {
String name;
String description;
}
}
这个时候你就可以像使用普通 bean 一样,将其注入到类中使用:
package cn.javaguide.readconfigproperties;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
@author shuang.kou
*/
@SpringBootApplication
public class ReadConfigPropertiesApplication implements InitializingBean {
private final LibraryProperties library;
public ReadConfigPropertiesApplication(LibraryProperties library) {
this.library = library;
}
public static void main(String[] args) {
SpringApplication.run(ReadConfigPropertiesApplication.class, args);
}
@Override
public void afterPropertiesSet() {
System.out.println(library.getLocation());
System.out.println(library.getBooks()); }
}
控制台输出:
湖北武汉加油中国加油
[LibraryProperties.Book(name=天才基本法, description........]
12.3. 通过@ConfigurationProperties
读取并校验
我们先将application.yml
修改为如下内容,明显看出这不是一个正确的 email 格式:
my-profile:
name: java 桃子
email: koushuangbwcx@
ProfileProperties
类没有加@Component
注解。我们在我们要使用ProfileProperties
的地方使用
@EnableConfigurationProperties
注册我们的配置 bean:
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
/**
@author shuang.kou
*/
@Getter
@Setter
@ToString
@ConfigurationProperties("my-profile")
@Validated
public class ProfileProperties {
@NotEmpty
private String name;
@NotEmpty
private String email;
//配置文件中没有读取到的话就用默认值
private Boolean handsome = Boolean.TRUE;
}
具体使用:
package cn.javaguide.readconfigproperties;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
@author shuang.kou
*/
@SpringBootApplication
@EnableConfigurationProperties(ProfileProperties.class)
public class ReadConfigPropertiesApplication implements InitializingBean {
private final ProfileProperties profileProperties;
public ReadConfigPropertiesApplication(ProfileProperties profileProperties) {
this.profileProperties = profileProperties;
}
public static void main(String[] args) {
SpringApplication.run(ReadConfigPropertiesApplication.class, args);
}
@Override
public void afterPropertiesSet() {
System.out.println(profileProperties.toString());
}
}
因为我们的邮箱格式不正确,所以程序运行的时候就报错,根本运行不起来,保证了数据类型的安全性:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed:
Property: my-profile.email
Value: koushuangbwcx@
Origin: class path resource [application.yml]:5:10
Reason: must be a well-formed email address
我们把邮箱测试改为正确的之后再运行,控制台就能成功打印出读取到的信息:
ProfileProperties(name=java 桃子, email=koushuangbwcx@163.com, handsome=true)
12.4. @PropertySource 读取指定的 properties 文件
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:website.properties")
@Getter
@Setter
class WebSite {
@Value("${url}")
private String url;
}
使用:
@Autowired
private WebSite webSite;
System.out.println(webSite.getUrl());//https://javaguide.cn/
13. Spring Boot 加载配置文件的优先级了解么?
Spring 读取配置文件也是有优先级的,直接上图:
MapStruct、ModelMapper、Dozer、Orika、JMapper 是 5 种常用的 Bean 映射工具。
综合日常使用情况和相关测试数据,个人感觉 MapStruct、ModelMapper 这两个 Bean 映射框架是最佳选择。
我们可以使用 Spring Boot Actuator 来对 Spring Boot 项目进行简单的监控。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
集成了这个模块之后,你的 Spring Boot 应用程序就自带了一些开箱即用的获取程序运行时的内部状态信息的 API。
比如通过 GET 方法访问 /health
接口,你就可以获取应用程序的健康指标。
数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。
Spring Boot 程序做请求参数校验的话只需要spring-boot-starter-web
依赖就够了,它的子依赖包含了我们所需要的东西。
16.1. 校验注解
JSR 提供的校验注解:
@Null
被注释的元素必须为 null@NotNull
被注释的元素必须不为 null@AssertTrue
被注释的元素必须为 true@AssertFalse
被注释的元素必须为 false@Min(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值@Max(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值@DecimalMin(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值@DecimalMax(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值@Size(max=, min=)
被注释的元素的大小必须在指定的范围内@Digits (integer, fraction)
被注释的元素必须是一个数字,其值必须在可接受的范围内@Past
被注释的元素必须是一个过去的日期@Future
被注释的元素必须是一个将来的日期@Pattern(regex=,flag=)
被注释的元素必须符合指定的正则表达式
Hibernate Validator 提供的校验注解:
@NotBlank(message =)
验证字符串非 null,且长度必须大于 0@Email
被注释的元素必须是电子邮箱地址@Length(min=,max=)
被注释的字符串的大小必须在指定的范围内@NotEmpty
被注释的字符串的必须非空@Range(min=,max=,message=)
被注释的元素必须在合适的范围内
使用示例:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@NotNull(message = "classId 不能为空")
private String classId;
@Size(max = 33)
@NotNull(message = "name 不能为空")
private String name;
@Pattern(regexp = "((^Man|^UGM$))", message = "sex 值不在可选范围")
@NotNull(message = "sex 不能为空")
private String sex;
@Email(message = "email 格式不正确")
@NotNull(message = "email 不能为空")
private String email;
}
16.2. 验证请求体(RequestBody)
我们在需要验证的参数上加上了@Valid
注解,如果验证失败,它将抛出MethodArgumentNotValidException
。默认情况下,Spring 会将此异常转换为 HTTP Status 400(错误请求)。
@RestController
@RequestMapping("/api")
public class PersonController {
@PostMapping("/person")
评论