Spring Boot


一、 @SpringBootApplication

**@SpringBootApplication**是三个注解的集合

注解

@Configuration

@EnableAutoConfiguration

@ComponentScan

作用

允许Spring Boot在上下文中注册额外的bean或导入其他配置类

启动Spring Boot的自动配置类

扫描@Component(@Service,@Controller)注解的Bean,默认扫描该类所在的包下的所有类

二、 Spring Bean相关

(1) @Autowried

自动导入对象到类中,被注入进的类同样要被Spring容器管理:Server类注入到Controller类中


(2)@Component、@Repository、@Service、@Controller

一般使用@autowired注解让Spring容器帮我们自动装配bean。想要把类标识成可用于@autowired注解自动装配的bean的类,可以采用如下注解

  • @Component:通用的注解,可以标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@component注解标注
  • @Repository:对应持久层,即Dao层,主要用于数据库相关的操作
  • @Service:对应服务层,主要设计一些复杂的逻辑,需要用到Dao层
  • @Controller: 对应Spring MVC控制层,主要用于接受用户的请求并调用Server层放回数据给前端页面

(3)RestController

@RestController注解是@Controller和@RequestBody的合计,表示这是个控制器bean,并且是将函数的返回值直接填入HTTP响应体重,是REST风格的控制器。

注释:单独使用@Controller和@RequestBody的话一般使用在要返回一个视图的情况,这种情况比较适用于传统的Spring MVC的应用,对应前后端不分离的情况

@Controller+@RequestBody返回JSON或者XML形式数据

关于@RestController和Controller的对比:@Controller返回的是一个页面 ,@RequestController返回的是一个JSON形式的数据


(4) @Scope

申明作用域

@Bean
@Scope("singleton")
public Person personSingleton() {
    return new Person();
}

四种常见的Spring Bean作用域:

  • singleton:唯一bean实例,Spring中的bean默认都是单例的
  • prototype:每次请求都会创建一个新的bean对象
  • request:每一次HTTP请求都会产生一个新的bean,该bean仅仅在当前的HTTP request内有效
  • session:每一次HTTP请求都会产生一个心的bean,改bean仅仅当前的HTTP session内生效

(5) @Configuration

一般用来申明配置类的,可以使用@Component注解代替,使用@Configuration更加语义化


三、处理常见的HTTP请求类型

5种常见的HTTP请求:

  • GET: 请求从服务器获取特定的资源: GET /users
  • POST: 在服务器创建一个新的资源 : POST /users
  • PUT: 更新服务器上的资源(客户端提供更新后的整个资源)。PUT/users/12
  • DELETE: 从服务器删除特定的资源。 DELETE /users/12
  • PATCH: 更新服务器上的资源(客户端提供更佳的属性,可以看做是部分更新),使用的较少。

四、前后端传值

(1)@pathVariable@RequestParm

@PathVariable用于获取路径的参数,@RequestParm用于查询获取参数

@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
         @PathVariable("klassId") Long klassId,
         @RequestParam(value = "type", required = false) String type ) {
...
}

如果我们的请求url是:/klasses/{klassID}/teachers?type=web
那么我们服务获取得到的数据就是:klassID=123456,type=web

(2)@RequestBody和@ResponseBody

  • @RequestBody

用于读取Request请求(可能是POST,PUT,DELETE,GET请求)的body部分并且Content-Type为application/json格式的数据,接受到数据之后会自动将数据绑定到java对象上去,系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的Body中的json字符串转换为java对象

  • @ResponseBody
    主要用来注释返回json数据给前端

五、读取配置文件

一般使用configuration.yml(代码取自Guide哥)

wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国加油!

my-profile:
  name: Guide哥   
  email: koushuangbwcx@163.com

library:
  location: 湖北武汉加油中国加油
  books:
    - name: 天才基本法
      description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。
    - name: 时间的秩序
      description: 为什么我们记得过去,而非未来?时间“流逝”意味着什么?是我们存在于时间之内,还是时间存在于我们之中?卡洛·罗韦利用诗意的文字,邀请我们思考这一亘古难题——时间的本质。
    - name: 了不起的我
      description: 如何养成一个新习惯?如何让心智变得更成熟?如何拥有高质量的关系? 如何走出人生的艰难时刻?

(1) @value

使用@value("${property}")读取比较简单的配置信息

@Vlaue("${wuhan2020}")
String wuhan2020

(2) @ConfigurationProperties(常用)

通过@ConfigurationProperties读取配置信息并与bean绑定

@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties {
    @NotEmpty
    private String location;
    private List<Book> books;
    
    @Setter
    @Getter
    @TosString
    static class Book {
        
        String name ;
        String description;
        
    }
    ....
}

(3) PropertyASource

读取指定的properties文件


六、参数校验

(1)为什么要参数校验

及时前端已经有了数据校验的情况下,还是为了防止用户使用一些HTTP工具绕过前端向后端请求一些违法数据

(2)常用的校验参数的注释

  • @NotEmpty 被注释的字符串的不能为 null 也不能为空
  • @NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Pattern(regex=,flag=)被注释的元素必须符合指定的正则表达式
  • @Email 被注释的元素必须是 Email 格式。
  • @Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max=, min=)被注释的元素的大小必须在指定的范围内
  • @Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Past被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个将来的日期

(3) 验证请求体@RequestBody

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    @NotNull(message = "classId 不能为空")
    private String classId;

    @Size(max = 33)
    @NotNull(message = "name 不能为空")
    private String name;

    @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围")
    @NotNull(message = "sex 不能为空")
    private String sex;

    @Email(message = "email 格式不正确")
    @NotNull(message = "email 不能为空")
    private String email;

}

我们需要在参数上加上**@Valid**注释,如果请求失败就会抛出 MethodArgumentNotValidException

@RestController
@RequestMapping("/api")
public class PersonController {

    @PostMapping("/person")
    public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) {
        return ResponseEntity.ok().body(person);
    }
}

七、 全局处理Controller层异常

相关注解

  1. @ControllerAdvice:注解定义全局异常处理类
  2. @ExceptionHandler:注解申明异常处理方法

八、事务

再要开启事务的地方加上 @Transactional 即可

@Trasactional(rollbackFor = Exception.class)
public void save(){
    ....
}
  • 如果不配置rollbackFor属性,事务只有在遇到RuntimeException的时候才会回滚
  • 上述的rollbackFor = Exception.class可以在遇到非运行时异常也会回滚

@Transactional一般可以作用于类或者是方法上

  • 作用于类:注释放在类撒上,表示所有的public方法都是配置相同的事务信息
  • 作用于方法:当类配置了@Trasactional,方法也配置了该注释,方法的事务会覆盖类的事务配置信息

九、 json数据处理

(1)、过滤json数据

@JsonIgnoreProperties作用于类上用于过滤掉特定的字段不解析

//生成json时将userRoles属性过滤
@JsonIgnoreProperties({"userRoles"})
public class User {

    private String userName;
    private String fullName;
    private String password;
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}

@JsonIgnore一般用于类的属性上,作用和上面的@JsonIgnoreProperties一样

public class User {
    private String userName;
    private String fullName;
    private String password;
    //生成json时将userRoles属性过滤
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}

(2)格式化json数据

@JsonFormat一般用来格式化Json数据

@JsonFormat(shape =JsonFormat.shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",timezone="GMT")
private Data data;

@JsonUnwrapped 扁平化对象


十、测试相关

@ActiveProfiles一般作用于测试类上, 用于声明生效的 Spring 配置文件

@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Slf4j
public abstract class TestBase {
  ......
}Copy to clipboardErrorCopied

@Test声明一个方法为测试方法

@Transactional被声明的测试方法的数据会回滚,避免污染测试数据。

@WithMockUser Spring Security 提供的,用来模拟一个真实用户,并且可以赋予权限。

@Test
    @Transactional
    @WithMockUser(username = "user-id-18163138155", authorities = "ROLE_TEACHER")
    void should_import_student_success() throws Exception {
        ......
    }