SpringBoot注解

HTTP请求

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

分别对应HTTP的GET, POST, PUT, DELETE, PATCH请求,简化了@RequestMapping的使用。

前后端参数传递

@RequestParam

将请求参数(在请求地址里面的参数 ?name=Tom)绑定到控制器的方法参数上

1
2
3
4
语法:@RequestParam(value="参数名",required="true/false",defaultValue="")
value:参数名,请求路径中的参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值

@PathVariable

用于将URL中的占位符绑定到方法参数上

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/api")
public class MyController {

@GetMapping("/user/{id}")
public String getUserById(@PathVariable("id") Long id) { // 如果参数名可URL中占位符名一样,可以不写注解的参数
return "User ID: " + id;
}
}

请求路径

1
GET /api/user/123

id的值就为123

还可以处理多个参数

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/api")
public class MyController {

@GetMapping("/order/{orderId}/item/{itemId}")
public String getOrderItem(@PathVariable("orderId") Long orderId, @PathVariable("itemId") Long itemId) {
return "Order ID: " + orderId + ", Item ID: " + itemId;
}
}

@RequestBody

用对象来接受请求体中的json格式数据

required:是否为必需参数,默认为true,如果请求中没有对应的内容会抛出异常。可以设置为false来允许请求体为空。

处理包含多个对象的JSON数组

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/api")
public class MyController {

@PostMapping("/users")
public String createUsers(@RequestBody List<User> users) {
return "Number of users created: " + users.size();
}
}

请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /api/users
Content-Type: application/json

[
{
"name": "John",
"age": 30
},
{
"name": "Jane",
"age": 25
}
]

接受复杂的JSON数据,对象套对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Address {
private String city;
private String state;
}

public class User {
private String name;
private int age;
private Address address;
}

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

@PostMapping("/user")
public String createUser(@RequestBody User user) {
return "User created: " + user.getName() + ", age: " + user.getAge() + ", city: " + user.getAddress().getCity();
}
}

请求:

1
2
3
4
5
6
7
8
9
10
11
POST /api/user
Content-Type: application/json

{
"name": "John",
"age": 30,
"address": {
"city": "New York",
"state": "NY"
}
}

对象属性与JSON中不一致

@ JsonProperty 给属性起别名

1
2
3
4
5
6
7
public class Address {
@JsonProperty(value = "city")
private String userCity;

@JsonProperty(value = "state")
private String userState;
}

@ResponseBody

@ResponseBody注解用于将控制器方法的返回值直接写入HTTP响应体中,而不是解析为视图名称。它通常用于RESTful Web服务,以返回JSON、XML或其他格式的数据。@ResponseBody可以作用在方法上或者类上(全局作用)。

返回简单字符串

1
2
3
4
5
6
7
8
9
10
@RestController
@RequestMapping("/api")
public class MyController {

@GetMapping("/greeting")
@ResponseBody
public String greeting() {
return "Hello, World!";
}
}

返回JSON

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping("/api")
public class MyController {

@GetMapping("/user")
@ResponseBody
public User getUser() {
User user = new User();
return user;
}
}

简化

使用@RestController简化

@RestController是一个组合注解,相当于@Controller@ResponseBody的组合。使用@RestController可以省略每个方法上的@ResponseBody注解。

Bean处理

@Autowired

将IOC容器中的对象自动注入

1
2
@Autowired
Animal animal;
  • 用在构造方法上,注入给构造方法中的参数

  • 用在方法上,注入给方法中的参数

多个同类型的Bean

如果Spring上下文中存在多个同类型的Bean,使用@Autowired时会引发NoUniqueBeanDefinitionException。此时可以使用@Qualifier注解来指定注入的具体Bean。

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
26
27
28
29
30
31
32
@Component("myService1")
public class MyService1 implements MyService {
public void serve() {
System.out.println("Service1 is serving...");
}
}

@Component("myService2")
public class MyService2 implements MyService {
public void serve() {
System.out.println("Service2 is serving...");
}
}

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

private final MyService myService;

@Autowired
public MyController(@Qualifier("myService1") MyService myService) {
this.myService = myService;
}

@GetMapping("/serve")
public String serve() {
myService.serve();
return "Service called";
}
}

使用@Primary

可以使用@Primary注解来标记一个Bean为首选的,当存在多个同类型的Bean时,Spring会优先注入标记了@Primary的Bean。

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
26
27
28
29
30
31
32
33
@Component
@Primary
public class MyService1 implements MyService {
public void serve() {
System.out.println("Service1 is serving...");
}
}

@Component
public class MyService2 implements MyService {
public void serve() {
System.out.println("Service2 is serving...");
}
}

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

private final MyService myService;

@Autowired
public MyController(MyService myService) {
this.myService = myService;
}

@GetMapping("/serve")
public String serve() {
myService.serve();
return "Service called";
}
}

@Component

用于将类标记为Spring管理的Bean。Spring会自动检测并注册这些被注解的类,通常用于实现自动扫描和依赖注入。

交给IOC容器管理。

可以通过value属性指定Bean的名称:

1
2
3
@Component("customService")
public class MyService {
}

然后在其他类中通过名称注入该组件:

1
2
3
4
5
6
7
@RestController
@RequestMapping("/api")
public class MyController {
@Autowired
@Qualifier("customService")
private MyService myService;
}

@Component的派生注解

Spring提供了一些特定场景下使用的派生注解,这些注解本质上都是@Component的变种,用于更清晰地表示组件的角色。

  • @Service用于标注服务层的组件:

  • @Repository用于标注数据访问层的组件,通常与数据库操作相关:\

  • @Controller用于标注控制器组件,处理HTTP请求:

  • @RestController @Controller@ResponseBody的组合

@Controller

用于标记一个类,使用他标记的类就是一个 SpringMVC Controller对象,即一个控制器类,Spring使用扫描机制查找所有基于该注解的控制器类。分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,使用了@ResquestMpping注解的方法才是真正处理请求的处理器。

@RequestMapping

如果没有指定请求方式,将接收GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT所有的HTTP请求方式。@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping 都是HTTP方法特有的快捷方式@RequestMapping的变体,分别对应具体的HTTP请求方式的映射注解。

1
@RequestMapping("/user/login") // https://localhost:8080/login/user

用在类上,该类的方法的url会跟在类的url后面

用在方法上,当前端访问注解内的地址时会调用该注解所标注的对象

@Respository

@Service

@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中.

@RestController

@Controller@ResponseBody的组合

@Scope

配置相关

@Bean

@Bean 注解是 Spring 框架中用来定义一个方法生成并返回一个 Spring Bean 的注解。这个注解通常用于配置类中(使用 @Configuration 注解的类)的方法上。通过 @Bean 注解,Spring 容器会将方法的返回值作为一个 Bean 注册到 Spring 容器中,以便在应用程序的其他部分中注入和使用。

1
2
3
4
5
6
7
8
@Configuration
public class MyAppConfig {

@Bean // 当启动项目时,spring会自动调用含@Bean注解的方法,并将这些方法的返回值注册为IOC容器中的bean
public MyService myService() {
return new MyServiceImpl();
}
}

默认情况下,Bean 的名称与方法名相同。如果需要,可以在 @Bean 注解中通过 name 属性指定 Bean 的名称。

1
2
3
4
@Bean(name = "customService")
public MyService myService() {
return new MyServiceImpl();
}

@Bean 方法可以接收参数,这些参数会自动从 Spring 容器中注入。这种方式可以实现 Bean 之间的依赖注入。

1
2
3
4
5
6
7
8
9
@Bean
public MyService myService(MyRepository myRepository) {
return new MyServiceImpl(myRepository);
}

@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}

在上面的例子中,myService() 方法需要一个 MyRepository 类型的参数,Spring 容器会自动查找并注入 myRepository() 方法返回的实例。

**@Bean@Component**:

  • @Bean 注解与 @Component 注解都用于定义 Spring Bean,但它们的用法不同。
  • @Component 通常用于标注类,然后由 @ComponentScan 自动发现并注册 Bean;而 @Bean 更适用于定义配置类中的方法,显式地注册 Bean。

@Configuration

@Configuration 用于定义配置类(Configuration Class)。通过在类上使用 @Configuration 注解,Spring 会将该类标识为一个配置类,并且会扫描其中定义的 @Bean 方法,自动注册这些方法返回的对象到 Spring 容器中,作为 Spring 的 Bean。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class MyAppConfig {

@Bean
public MyService myService() {
return new MyServiceImpl();
}

@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}

**@Configuration@Component**:

  • 虽然 @Configuration 类似于 @Component,两者都可以用来定义 Spring Bean,但 @Configuration 更适用于配置类。
  • @Component 更倾向于标注普通的组件类,而 @Configuration 则专门用于定义 Beans,并且这些 Bean 方法可以互相调用。

Full (完整) 模式与 Lite (轻量) 模式

  • 当一个类被 @Configuration 注解标注时,Spring 会默认将该类作为一个代理类处理,这是 Full 模式。在这种模式下,@Bean 方法可以进行跨方法调用,保持单例模式。
  • 而如果一个类没有 @Configuration 注解(仅使用 @Component 等),则它处于 Lite 模式,@Bean 方法之间的调用不会通过代理处理,可能导致多个实例。

@ConfigurationProperties

@ConfigurationProperties 是 Spring 框架中的一个注解,用于将外部配置属性(如 application.propertiesapplication.yml 中的配置)映射到 Java 类的字段上。通过这种方式,可以将配置文件中的属性集中到一个配置类中管理,从而更加方便地使用和维护这些配置。

@ConfigurationProperties 注解通常用于标注在一个 POJO 类上,Spring 会根据属性的前缀(通过 prefix 属性指定)将外部配置文件中的属性映射到这个类的字段上。

1
2
3
4
5
6
7
@ConfigurationProperties(prefix = "app")
public class AppProperties {

private String name;
private String description; // POJO是驼峰命名,appName,配置文件中是app-name Spring会自动对应
// getters and setters
}

在上面的例子中,假设你的 application.properties 文件中有以下内容:

1
2
app.name=MyApp
app.description=This is my application

Spring 会自动将这些属性注入到 AppProperties 类的 namedescription 字段中。

**启用 @ConfigurationProperties**:

要使 @ConfigurationProperties 生效,通常需要将配置类标注为一个 Spring 管理的 Bean。常见的做法是在配置类上添加 @Component 注解,或者在配置类所在的包路径上使用 @EnableConfigurationProperties 注解。

1
2
3
4
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
}
1
2
3
4
5
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
// 配置相关内容
}

@Value 的区别:

都可以用于从配置文件中获取属性值,但它们的应用场景有所不同:

  • @Value 适合用于单个属性的注入,通常在少量配置或不需要集中管理时使用。
  • @ConfigurationProperties 适合用于将相关的配置属性集中到一个类中,便于管理和使用,尤其是涉及到大量配置时。

@PropertySource

@PropertySource 是 Spring 框架中的一个注解,用于指定外部属性文件(如 .properties 文件)的位置,并将其加载到 Spring 的环境中,以便在应用程序中使用这些配置属性。

基本用法

  • @PropertySource 注解通常用于配置类中,用来指定一个或多个属性文件的位置。
  • 这些属性文件会被 Spring 加载,并且可以通过 @Value 注解或 @ConfigurationProperties 注解将属性注入到 Spring 管理的 Bean 中。
1
2
3
4
5
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
// 配置类内容
}

在上面的例子中,application.properties 文件被加载并可以在应用中使用。

@Value

用于注入外部化配置值到Spring Bean的注解。它可以将属性文件中的值、系统属性、环境变量或任意字符串注入到Bean的字段、构造函数或方法参数中。

例如:

1
2
app.name=My Application
app.version=1.0.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {

@Value("${app.name}")
private String appName;

@Value("${app.version}")
private String appVersion;

public void printConfig() {
System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
}
}

一个简单应用实例:

某段业务代码需要配置文件中的信息:

1
2
3
4
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;

我们需要从配置文件中获取:

1
2
3
4
5
6
example:
alioss:
endpoint:
access-key-id:
access-key-secret:
bucket-name:

我们先写一个POJO类用来读取这些配置信息:

1
2
3
4
5
6
7
8
9
10
@Component
@ConfigurationProperties(prefix = "example.alioss")
@Data
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;

}

然后再写一个配置类来读取这个POJO,并实例化一个对象给IOC容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
@Slf4j
public class OssConfiguration {

@Bean // 实例化了一个AliOssUtil对象给IOC容器管理,当在用到AliOssUtil时,就是使用了这个对象
@ConditionalOnMissingBean // 只允许一个实例
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) { // personProperties 会自动注入
return new AliOssUtil(aliOssProperties.getEndpoint()
, aliOssProperties.getAccessKeyId()
, aliOssProperties.getAccessKeySecret()
, aliOssProperties.getBucketName());
}
}

使用到的地方,可以通过自动注入拿到有配置信息的对象

1
2
@Autowired
private AliOssUtil aliOssUtil;

参数校验

Bean字段验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@NotEmpty // 字段不为null且不为空字符串
@NotBlank // 字段不为null且必须包含至少一个非空白字符
@Null // 字段必须为null
@NotNull // 字段不能为空
@AssertTrue // 字段必须为true
@AssertFalse // 字段必须为false
@Pattern(regex=, flag=) // 字段必须符合指定的正则表达式
@Email // 字段必须是有效的电子邮件地址
@Min(value) // 字段的值必须大于或等于指定的最小值
@Max(value) // 字段的值必须小于或等于指定的最大值
@DecimalMin(value) // 字段的值必须大于或等于指定的最小值(用于小数)
@DecimalMax(value) // 字段的值必须小于或等于指定的最大值(用于小数)
@Size(max=, min=) // 字段的大小必须在指定范围内
@Digits(integer=, fraction=) // 字段的整数位数和小数位数必须在指定范围内
@Past // 字段的值必须是过去的日期
@Future // 字段的值必须是未来的日期

@Valid

@Valid注解用于触发对象的校验。它通常用在方法参数或字段上,表示需要对该对象进行校验。

@Validated

@Validated注解用于校验分组(Group Validation),它可以在类或方法级别使用。与@Valid不同,@Validated可以指定特定的校验组,从而实现分组校验。

同时,对象在指明校验时也需要指明分组

1
2
3
4
5
6
7
public class User {
@NotEmpty(groups = UserGroup.class)
private String username;

@NotEmpty
private String password;
}

统一异常处理

@ControllerAdvice

@RestControllerAdvice@ControllerAdvice@ResponseBody 的结合体。

@ExceptionHandler

@ExceptionHandler注解是Spring框架中的一个用于处理异常的方法注解。它通常与@ControllerAdvice或控制器类结合使用,定义一个方法来处理特定类型的异常,从而实现全局或局部的异常处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
return new ResponseEntity<>("Handled RuntimeException: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>("Handled Exception: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

JPA数据持久化

@Transactional

@Transactional作用:就是在当前这个方法执行开始之前来开启事务,方法执行完毕之后提交事务。如果在这个方法执行的过程当中出现了异常,就会进行事务的回滚操作。

@Transactional注解:我们一般会在业务层当中来控制事务,因为在业务层当中,一个业务功能可能会包含多个数据访问的操作。在业务层来控制事务,我们就可以将多个数据访问操作控制在一个事务范围内。

  • 写在方法上,该方法交给spring进行事务管理
  • 写在类上,该类中所有方法交给spring进行事务管理
  • 写在接口上,该接口下所有的实现类当中所有的方法都交给spring 进行事务管理

JSON数据处理

@JsonIgnoreProperties

@JsonIgnoreProperties注解用于在序列化或反序列化时忽略指定的属性。

用法

1
2
3
4
5
6
@JsonIgnoreProperties({ "name", "pasword" })
public class User {
private String name;
private String password;
private int age;
}

解释

  • 该注解可以放在类上,指定在序列化和反序列化时要忽略的属性列表。

  • 常用于忽略某些敏感数据或不需要传递的数据。

@JsonIgnore

@JsonIgnore注解用于在序列化和反序列化时忽略单个字段。

  • 用法

    1
    2
    3
    4
    5
    6
    7
    8
    public class User {
    private String name;

    @JsonIgnore
    private String password;

    private int age;
    }
  • 解释

    • 标记在字段或getter方法上,被标记的字段不会被序列化或反序列化。
    • 适用于需要忽略单个字段的情况。

@JsonFormat

@JsonFormat注解用于指定日期、时间等格式化模式的序列化和反序列化。

  • 用法

    1
    2
    3
    4
    5
    6
    7
    public class Event {
    private String name;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")也可以这样
    private Date eventDate;
    }
  • 解释

    • shape:指定序列化的形状,比如JsonFormat.Shape.STRING将日期格式化为字符串。
    • pattern:指定日期、时间等格式的模式。
    • 常用于处理日期和时间格式的转换。

@JsonUnwrapped

@JsonUnwrapped注解用于将嵌套对象的属性“展开”到父对象中进行序列化或反序列化。

  • 用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Name {
    private String firstName;
    private String lastName;
    }

    public class User {
    private int id;

    @JsonUnwrapped
    private Name name;
    }
  • 解释

    • @JsonUnwrapped应用于一个对象字段时,该对象的属性将直接作为父对象的属性被序列化或反序列化,而不是作为嵌套对象。
    • 适用于需要将嵌套对象的属性直接平铺到父对象中的场景。

配置启动

@SpringBootApplication

这是一个组合注解,包括@SpringBootConfiguration@EnableAutoConfiguration,和@ComponentScan。标记一个主配置类,Spring Boot可以通过该类启动应用程序。