文章目录
- 1.启动注解
- 2.Controller
- 3.Controller 中地址映射
- 4.Controller参数映射
- 5.Controller参数验证
- 6.单例的bean类创建
- 7.实体类
- 8.配置类
- 9.导入配置文件
- 10.事务注解
- 11.全局异常处理
- 12.自动注入
- 13.条件注解
1.启动注解
@SpringBootApplication
- @SpringBootApplication 是一个复合注解,包含了 @SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan 这三个注解
(1)@ComponentScan
- @ComponentScan 的功能其实就是自动扫描并加载符合条件的组件或 bean 定义,最终将这些 bean 定义加载到容器中。我们可以通过 basePackages 等属性指定 @ComponentScan 自动扫描的范围,如果不指定,则默认 Spring 框架实现从声明@ComponentScan 所在类的 package 进行扫描,默认情况下是不指定的,所以 SpringBoot的启动类最好放在 root package 下。
(2)@EnableAutoConfiguration
- @EnableAutoConfiguration 可以帮助 SpringBoot 应用将所有符合条件的 @Configuration 配置都加载到当前 SpringBoot 创建并使用的 IoC 容器。借助于 Spring 框架原有的一个工具类:SpringFactoriesLoader 的支持,@EnableAutoConfiguration 可以智能的自动配置功效才得以大功告成。
(3)@SpringBootConfiguration
- @SpringBootConfiguration 继承自 @Configuration,二者功能也一致,标注当前类是配置类, 并会将当前类内声明的一个或多个以 @Bean 注解标记的方法的实例纳入到 spring 容器中,并且实例名就是方法名。
2.Controller
@RestController
- @RestController 注解相当于 @ResponseBody + @Controller 合在一起的作用。
- 直接使用接口方法的返回结果,经过 JSON / XML 等序列化方式,最终返回。也就是说,无需使用 InternalResourceViewResolver 解析视图,返回 HTML 结果。
- 目前主流的架构,都是前后端分离的架构,后端只需要提供 API 接口,仅仅返回数据。而视图部分的工作,全部交给前端来做。也因此,我们项目中 99.99% 使用 @RestController 注解。
(1)@Controller
- 添加在类上,表示这是控制器 Controller 对象,处理 http 请求。
- name 属性:该 Controller 对象的 Bean 名字。允许空。
(2)@ResponseBody
- 将方法返回的对象直接在浏览器上展示成 json 格式。
3.Controller 中地址映射
@RequestMapping
- 一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
- 添加在类或方法上,标记该类/方法对应接口的配置信息。
简化注解
(1)@GetMapping
- 等同于 @RequestMapping(method = RequestMethod.GET)
(2)@PostMapping
- 等同于 @RequestMapping(method = RequestMethod.POST)
4.Controller参数映射
(1)@PathVariable
- 添加在方法参数上,标记接口路径和方法参数的映射关系。例如, /getUser/001,可接收 001 作为参数。
@Controller
@RequestMapping("/User")
public class HelloWorldController {
@RequestMapping("/getUser/{uid}")
public String getUser(@PathVariable("uid")Integer id, Model model) {
System.out.println("id:"+id);
return "user";
}
}
(2)@RequestParam
- 添加在方法参数上,标记该方法参数对应的请求参数的信息。
- name 和 value 等效。
- required 属性:参数是否必须传。默认为 true ,表示必传。
- defaultValue 属性:参数默认值。
- 获取 GET 请求参数值:http://localhost:8888/User/getUser?id=1&age=20
@Controller
@RequestMapping("/User")
public class HelloWorldController {
@GetMapping("/getUser")
public String getUser(@RequestParam("id") Integer id, @RequestParam("age") Integer age) {
System.out.println("id:"+id);
return "user";
}
}
(3)@RequestHeader
- 把 Request 请求 header 部分的值绑定到方法的参数上。
(4)@CookieValue
- 把 Request header 中关于 cookie 的值绑定到方法的参数上。
5.Controller参数验证
@Validated、@Valid
- 分组校验:
- @Validated 支持分组验证,可以更细致地控制验证过程。此外,由于它是 Spring 专有的,因此可以更好地与 Spring 的其他功能(如 Spring 的依赖注入)集成。
- @Valid 主要支持标准的 Bean 验证功能,不支持分组验证。
- 嵌套校验:
- @Validated 不支持嵌套验证。
- @Valid 支持嵌套验证,可以嵌套验证对象内部的属性。
- @Valid 注解的地方,也多了【构造方法】和【方法返回】,所以在有这方面的诉求的时候,也只能使用 @Valid 注解。
@Validated
对象上使用
@Controller
@RequestMapping("/User")
public class HelloWorldController {
@RequestMapping("/getUser")
public String getUser(@Validatd Sysparam model) {
System.out.println("id:"+id);
return "user";
}
}
参数是非对象格式时
@Controller
@RequestMapping("/User")
@Validatd
public class HelloWorldController {
@RequestMapping("/getUser")
public String getUser(@NotBlank String model) {
System.out.println("id:"+id);
return "user";
}
}
分组校验
- 定义两个接口,CreationGroup 用于创建时指定的分组,UpdateGroup 用于更新时指定的分组。
public interface CreationGroup {
}
public interface UpdateGroup {
}
- 创建一个UserBean用户类,分别校验 username 字段不能为空和id字段必须大于0,然后加上CreationGroup和 UpdateGroup 分组。
@Data
public class UserBean {
@NotEmpty(groups = {CreationGroup.class})
private String username;
@Min(value = 18)
private Integer age;
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 1, groups = {UpdateGroup.class})
private Long id;
}
- 在ValidationController 中新建两个接口 #updateUser() 和 #createUser()。#createUser() 中对 username 做校验,#updateUser() 中对 id 做校验。
@RestController
@RequestMapping("validation")
public class ValidationController {
@GetMapping("createUser")
public UserBean createUser(@Validated({CreationGroup.class}) UserBean userBean){
return userBean;
}
@GetMapping("updateUser")
public UserBean updateUser(@Validated({UpdateGroup.class}) UserBean userBean){
return userBean;
}
}
@Valid
嵌套校验
@Data
public class UserBean {
@NotEmpty(groups = {CreationGroup.class})
private String username;
@Min(value = 18)
private Integer age;
private String email;
@Min(value = 1 ,groups = {UpdateGroup.class})
private Long id;
//嵌套验证必须要加上@Valid
@Valid
@NotNull
private AddressBean address;
}
@Data
public class AddressBean {
@NotBlank
private String country;
@NotBlank
private String city;
}
@PostMapping("nestValid")
public UserBean nestValid(@Validated @RequestBody UserBean userBean){
System.out.println(userBean);
return userBean;
}
空和非空检查
@Null
- 被注释的元素必须为 null。
@NotNull
- 被注释的元素必须不为 null。
@NotEmpty
- 集合对象的元素不为 0 ,即集合不为空,也可以用于字符串不为 null 。
@NotBlank
- 只能用于字符串不为 null ,并且字符串 #trim() 以后 length 要大于 0 。
数值检查
@DecimalMin(value)
- 元素必须是一个数字,其值必须大于等于指定的最小值。由于可能存在舍入错误问题,double 和 float 不受支持。
@DecimalMax(value)
- 元素必须是一个数字,其值必须小于等于指定的最大值。由于可能存在舍入错误问题,double 和 float 不受支持。
@Digits (integer, fraction)
- 限制必须为一个小数,且整数部分的位数不能超过 integer,小数部分的位数不能超过 fraction。
@Min(value)
- 被注释的元素必须是一个数字,其值必须大于等于指定的最小值。
@Max(value)
- 被注释的元素必须是一个数字,其值必须小于等于指定的最大值。
@Negative
- 负数校验。校验的值一定得是负数。包含 null 值。
@NegativeOrZero
- 负数和零值校验。
@Positive
- 正数校验。
@PositiveOrZero
- 比 @Positive 多了个 0。
Boolean 值检查
@AssertTrue
- 被注释的元素必须为 true。接受 null 值。
@AssertFalse
- 被注释的元素必须为 false。接受 null 值。
长度检查
@Size(max, min)
- 被注释的元素的大小必须在指定的范围内。支持的类型有:
- 字符串(估算字符序列的长度)
- 集合(估算集合大小)
- Map(估算map大小)
- 数组(估算数组长度)
@Length(min, max)
- 被注释的字符串的大小必须在指定的范围内。
日期检查
@Future
- 注释日期必须是一个将来的日期。
@FutureOrPresent
- 判断日期是否是将来或现在日期。
@Past
- 被注释的元素必须是一个过去的日期。
@PastOrPresent
- 判断日期是否是过去或现在日期。
@DateTimeFormat(pattern = “yyyy-MM-dd”)
将String类型转为Date / LocalDate / LocalDateTime类型
其它检查
@Pattern(value)
- 被注释的元素必须符合指定的正则表达式。
- 被注释的元素必须是电子邮箱地址。
@URL(protocol=,host=,port=,regexp=,flags=)
- 被注释的字符串必须是一个有效的 URL 。
@SafeHtml
- 判断提交的 HTML 是否安全。例如说,不能包含 javascript 脚本等等。
6.单例的bean类创建
(1)@Service
- 作用于业务逻辑层
(2)@Repository
- 作用于持久层
(3)@Component
- 最普通的组件,可以被注入到 spring 容器进行管理
@PostConstruct
- 构造方法 > @Autowired/@Value > @PostConstruct
7.实体类
(1)@Entity
(2)@Table(name = “数据库表名”)
@Id
@Column
@JsonProperty(“file_id”)
- JSON 序列化时指定别名。
@JsonIgnoreProperties({“xx”})
- 作用于类。在序列化与反序列化中忽略xx属性。
@JsonIgnore
- 作用于属性,使相应字段不进行序列化与反序列化。
@JsonInclude(JsonInclude.Include.NON_EMPTY)
- 作用于类,用于设置序列化方式。
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH-mm-ss”)
- 作用于属性,可以把 Date 类型直接转化为设定好的格式 。
@JsonAlias
- 作用于属性,为属性设置别名,在反序列化时,让属性接收多个 json 字段的值 eg: @JsonAlias({“fileId”,“file_id”})
(3)@Data
所有属性:@Getter
所有属性:@ToString
- 因为默认情况下,@Data 注解不会处理父类的属性。所以需要我们通过 @ToString(callSuper = true) ,声明需要调用父类对应的方法。
所有属性:@EqualsAndHashCode
- 在实体类中,我们可能会声明一个抽象父类 AbstractEntity,而该类里有一个 id 编号属性。需要使用 @EqualsAndHashCode(callSuper = true) 注解。
非 final 修饰的属性:@Setter
final 修改的属性:@RequiredArgsConstructor
- RequiredArgsConstructor 是 Lombok 库中的一个注解,用于自动生成 Java 类的构造函数。当类中有一些字段被标记为 final 或者没有默认值时,通常需要一个构造函数来初始化这些字段。使用 RequiredArgsConstructor 可以自动生成这样的构造函数,避免了手动编写这些构造函数的代码。
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MyClass {
private final String requiredField;
private String optionalField;
}
- Lombok 会自动生成一个构造函数,该构造函数接受一个 requiredField 参数,并初始化 requiredField 字段。注意,由于 requiredField 是 final 的,所以它只能被赋值一次,即只能通过构造函数进行初始化。
(4)@NoArgsConstructor
(5)@AllArgsConstructor
(6)@Builder 或 @Accessors(chain=true)
(7)@Slf4j
- @Slf4j 注解,添加在类上,给该类创建 Slf4j Logger 静态属性。
- Lombok 还提供了 @CommonsLog、@Flogger、@Log、@JBossLog、@Log4j、@Log4j2、@Slf4jX 注解,支持持不同的 Logger 组件。因为 Spring Boot 使用 Slf4j 日志门面框架,所以绝大多数情况下,我们都是使用 @Slf4j 注解。
8.配置类
(1)@Configuration
(2)@Bean
- 方法参数默认注入方式为 Autowired,即先根据类型匹配,若有多个在根据名称进行匹配
- 复杂类型可以通过 @Qualifier(value=“XXX”) 限定
- 普通类型使用 @Value(XXX) 指定
(3)@Scope
@Configuration
public class BeanConfig() {
@Bean(name = "user")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 多例模式
User user() {
return User.user();
}
@Bean(name = "userZero")
User userZero(String aaaa) {
return User.userZero();
}
@Bean(name = "userOne")
User userOne(@Value("${jdbc.driverClass}") String driverClassName, @Value("${jdbc.jdbcUrl}") String url) {
return User.userOne();
}
@Bean(name = "userTwo")
User userTwo(@Qualifier(value = "dataSource") DataSource dataSource) {
return User.userTwo();
}
}
9.导入配置文件
(1)@ImportResource引入.xml 类型的配置文件
一般用于启动类上。用于引入 .xml 类型的配置文件,在 spring boot 中已经被配置类替代。
@ImportResource(locations={"classpath:app-*.xml"})
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
(2)@PropertySource引入*.Properties或者 .yml
- 一般用在 javabean 的类名上。用于给 javabean 注入值。
配置文件变量注入
(1)@Value
- 指定前缀,将配置文件中的单个值注入到 Bean 中。
@Component
@PropertySource(value = {"demo/props/demo.properties"})
public class ReadByPropertySourceAndValue {
@Value("${demo.name}")
private String name;
@Value("${demo.sex}")
private int sex;
@Value("${demo.type}")
private String type;
@Override
public String toString() {
return "ReadByPropertySourceAndValue{" +
"name='" + name + '\'' +
", sex=" + sex +
", type='" + type + '\'' +
'}';
}
}
(2)@ConfigurationProperties(“foo.datasource”)
- 如果在配置文件中没有配置,则该Bean的各属性为默认值。
- 指定前缀,将配置文件中的所有值注入到 Bean 中。
- 组合使用,可以将属性文件与一个 Java 类绑定,将属性文件中的变量值注入到该 Java 类的成员变量中。
- 需要加上 @Component 注解才能绑定并注入 IOC 容器中,若不加上 @Component,则会无效。
@Component
@PropertySource(value = {"demo/props/demo.properties"})
@ConfigurationProperties(prefix = "demo", ignoreUnknownFields = true)
public class ReadByPropertySourceAndConfProperties {
private String name;
private int sex;
private String type;
public void setName(String name) {
this.name = name;
}
public void setSex(int sex) {
this.sex = sex;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public int getSex() {
return sex;
}
public String getType() {
return type;
}
@Override
public String toString() {
return "ReadByPropertySourceAndConfProperties{" +
"name='" + name + '\'' +
", sex=" + sex +
", type='" + type + '\'' +
'}';
}
}
(3)@EnableConfigurationProperties(ServerProperties.class)
- 让使用了 @ConfigurationProperties 注解的配置类生效,将该类注入到 IOC 容器中,交由 IOC 容器进行管理,此时则不用再配置类上加上 @Component。
为什么需要@EnableConfigurationProperties
https://blog.csdn.net/weixin_42329623/article/details/131507421
@Component
@EnableConfigurationProperties(ServerProperties.class)
public class Test implements ApplicationRunner {
@Autowired
DemoConfig demoConfig;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(demoConfig);
}
}
@ConfigurationProperties(prefix = "demo")
@Data
public class DemoConfig {
private String name;
private Integer age;
}
10.事务注解
(1)@Transactional
11.全局异常处理
(1)@ControllerAdvice + @ExceptionHandler
- @ControllerAdvice:表示它是一个增强版的 controller,用来开启全局的异常捕获。
- @ExceptionHandler:表示这是一个异常处理方法,说明捕获哪些异常,对哪些异常进行处理。
声明异常处理方法
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public BaseResult handleException(Exception e){
return new BaseResult(e.getCode(),false,e.getMessage());
}
}
12.自动注入
(1)@Autowired + @Qualifier(“dataSource2”)
- @Autowired :按类型注入。
- @Qualifier(“dataSource2”):如果接口有多个实现类。需要与 @Autowired 配合使用,实现按名称。注:使用 Qualifier 是在使用 Autowired 的基础上才有意义的。
(2)@Resource(name = “dataSource2”)
- Resource 等于 Autowired+Qualifier 注解,如果我们不给 Resource 指定 name 属性时,那 么Resource 是按照类型注入的,此时如果接口有多个实现类,就会报错。
13.条件注解
- 用于声明在配置类或者创建 Bean 的方法上
(1)@Profile
- 在 Spring3.1 版本时,为了满足不同环境注册不同的 Bean ,引入了 @Profile 注解
- 在测试环境下,我们注册单机 MySQL 的 DataSource Bean。
- 在生产环境下,我们注册集群 MySQL 的 DataSource Bean。
@Configuration
public class DataSourceConfiguration {
@Bean
@Profile("DEV")
public DataSource devDataSource() {
// ... 单机 MySQL
}
@Bean
@Profile("PROD")
public DataSource prodDataSource() {
// ... 集群 MySQL
}
}
Conditional 相关注解
- @ConditionalOnWebApplication:当前项目是 Web 项目的条件下
- @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
- @ConditionalOnClass:当类路径下有指定类的条件下
- @ConditionalOnMissingClass:当类路径下没有指定类的条件下
- @ConditionalOnBean:当容器里有指定 Bean 的条件下
- @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
- @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
- @ConditionalOnProperty:指定的属性是否有指定的值
- 啊
- @ConditionalOnResource:类路径是否有指定的值
- @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
- @ConditionalOnJava:基于 Java 版本作为判断条件
- @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置