吐血整理!40个SpringBoot常用注解,看完秒变开发大神

5 阅读13分钟

吐血整理!40个SpringBoot常用注解,看完秒变开发大神

引言

在当今的 Java 开发领域,Spring Boot 无疑是最耀眼的明星框架之一。它以其强大的自动配置功能和简洁的开发模式,让开发者们从繁琐的 XML 配置中解脱出来,大大提高了开发效率。而在 Spring Boot 的世界里,注解就像是一把把神奇的钥匙,能够开启各种强大功能的大门。无论是组件扫描、依赖注入,还是 Web 开发、事务管理,注解都发挥着不可或缺的作用。今天,就让我们一起深入探索 40 个 Spring Boot 常用注解,解锁 Spring Boot 开发的更多奥秘!

Spring Boot 注解入门基础

在深入了解这 40 个常用注解之前,我们先来简单了解一下 Spring Boot 注解的基本概念和作用。注解,简单来说,就是一种元数据,它为我们的代码提供了额外的信息。在 Spring Boot 中,注解就像是一个个 “魔法标记”,告诉 Spring 容器如何处理我们的代码,比如哪些类是组件,哪些方法需要被调用,以及如何进行依赖注入等等 。通过使用注解,我们可以将原本繁琐的 XML 配置简化为简洁的代码注解,大大提高了开发效率和代码的可读性。而且,注解还能帮助我们实现代码的解耦,使得各个模块之间的依赖关系更加清晰,便于维护和扩展。

40 个常用注解大揭秘

(一)核心与启动类注解

@SpringBootApplication

@SpringBootApplication是 Spring Boot 应用的核心注解,它是一个组合注解,相当于@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan这三个注解的集合。@SpringBootConfiguration用于标记当前类为配置类,等同于@Configuration,表明该类可以定义 Bean 方法;@EnableAutoConfiguration开启自动配置机制,Spring Boot 会根据项目中引入的依赖和配置文件,自动配置应用所需的 Bean;@ComponentScan则用于自动扫描组件,默认扫描当前包及其子包下的所有组件 。通常,我们会将@SpringBootApplication注解添加到 Spring Boot 应用的启动类上,如下所示:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MySpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApp.class, args);
    }
}

这样,Spring Boot 在启动时就会自动完成组件扫描、自动配置等核心功能,让我们的应用能够快速搭建并运行起来 。

(二)Bean 定义与管理注解

  1. @Component:这是一个通用的组件注解,用于将一个类标识为 Spring 管理的组件(Bean),Spring 容器会自动扫描并注册带有该注解的类。比如我们定义一个工具类Utils,可以使用@Component注解将其纳入 Spring 容器管理:

import org.springframework.stereotype.Component;

@Component
public class Utils {
    public String sayHello() {
        return "Hello from Utils";
    }
}
  1. @Service:专门用于标记服务层组件,是@Component的特化版本,语义更加明确,用于表示业务逻辑服务。例如,我们有一个用户服务类UserService

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public String getUserInfo() {
        return "User information";
    }
}
  1. @Repository:用于标记数据访问层组件,也是@Component的特化注解,它除了将类标识为组件外,还能自动处理数据库操作的异常。以用户数据访问类UserRepository为例:

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    public void saveUser() {
        // 模拟保存用户到数据库的操作
    }
}
  1. @Controller:标记类为 Spring MVC 的控制器,用于接收前端请求。在传统的 MVC 项目中,@Controller通常配合视图解析器返回页面。比如我们有一个控制器类HomeController

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {
    @RequestMapping("/")
    public ModelAndView home() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("home");
        return modelAndView;
    }
}
  1. @Bean:通常用于配置类中,将方法的返回值注册为一个 Bean。例如,我们在配置类中定义一个数据源 Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class DataSourceConfig {
    @Bean
    public HikariDataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("root");
        config.setPassword("password");
        return new HikariDataSource(config);
    }
}
  1. @Configuration:标记一个类为配置类,替代传统的 XML 配置文件,类中可以通过@Bean注解定义自定义的 Bean。如上述的DataSourceConfig类,通过@Configuration标记为配置类,然后在其中定义了dataSource Bean。

  2. @Scope:用于声明一个 Spring Bean 实例的作用域,常见的作用域有单例模式(singleton,默认)、原型模式(prototype)等。比如,我们希望某个 Bean 每次被请求时都创建一个新的实例,可以使用@Scope("prototype")


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class BeanScopeConfig {
    @Bean
    @Scope("prototype")
    public MyPrototypeBean prototypeBean() {
        return new MyPrototypeBean();
    }
}
  1. @Primary:当存在多个相同类型的 Bean 时,使用@Primary注解可以指定一个优先被注入的 Bean。假设我们有两个实现了UserService接口的类UserServiceAUserServiceB,并且希望在注入时优先使用UserServiceA,可以这样标注:

import org.springframework.stereotype.Service;

@Service
@Primary
public class UserServiceA implements UserService {
    @Override
    public void getUserInfo() {
        System.out.println("User Service A");
    }
}
  1. @PostConstruct:用于标注一个方法,该方法会在 Bean 被创建并完成属性注入后立即执行,常用于初始化操作。例如:

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private String message;

    @PostConstruct
    public void init() {
        message = "Initializing UserService";
    }

    public String getMessage() {
        return message;
    }
}
  1. @PreDestroy:与@PostConstruct相反,它标注的方法会在 Bean 被销毁之前执行,常用于资源清理等操作:

import javax.annotation.PreDestroy;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @PreDestroy
    public void destroy() {
        System.out.println("Destroying UserService");
    }
}

(三)依赖注入注解

  1. @Autowired:由 Spring 框架提供,用于自动注入依赖对象,它默认按照类型进行装配。比如在UserController中注入UserService

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/user")
    public String getUser() {
        return userService.getUserInfo();
    }
}
  1. @Resource:这是 JDK 提供的注解,用于依赖注入。它默认按照名称进行装配,如果找不到与名称匹配的 Bean,才会按照类型进行装配。使用示例如下:

import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @Resource(name = "userService")
    private UserService userService;

    @GetMapping("/user")
    public String getUser() {
        return userService.getUserInfo();
    }
}
  1. @Qualifier:通常与@Autowired结合使用,当存在多个相同类型的 Bean 时,通过@Qualifier可以指定要注入的具体 Bean 的名称,从而消除歧义。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private final UserService userService;

    @Autowired
    @Qualifier("userServiceA")
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/user")
    public String getUser() {
        return userService.getUserInfo();
    }
}

(四)Web 开发注解

  1. @RequestMapping:这是一个通用的请求映射注解,用于将 HTTP 请求映射到控制器的方法上,支持 GET、POST、PUT、DELETE 等多种请求方法。它可以标注在类或方法上,标注在类上时,表示类中的所有响应请求的方法都是以该类路径为父路径。例如:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public String getUser() {
        return "Get user";
    }
}
  1. @GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping:这些都是@RequestMapping的特化注解,分别对应 HTTP 的 GET、POST、PUT、DELETE、PATCH 请求方法,语义更加清晰,使用也更加方便。例如:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/getById/{id}")
    public String getUserById(@PathVariable Long id) {
        return "User ID: " + id;
    }

    @PostMapping("/add")
    public String addUser(@RequestBody User user) {
        return "Add user: " + user.getName();
    }

    @PutMapping("/update")
    public String updateUser(@RequestBody User user) {
        return "Update user: " + user.getName();
    }

    @DeleteMapping("/delete/{id}")
    public String deleteUser(@PathVariable Long id) {
        return "Delete user with ID: " + id;
    }

    @PatchMapping("/patch/{id}")
    public String patchUser(@PathVariable Long id) {
        return "Patch user with ID: " + id;
    }
}
  1. @RequestBody:用于将 HTTP 请求体的内容(如 JSON、XML)转换为 Java 对象,通常用于接收前端传递的数据,标注在方法的参数上。比如上述addUserupdateUser方法中,通过@RequestBody接收前端传递的User对象。

  2. @ResponseBody:将方法的返回值转换为指定格式(如 JSON、XML)作为 HTTP 响应的内容返回给客户端,通常与@RequestMapping@GetMapping等注解一起使用在方法上。而@RestController注解实际上是@Controller@ResponseBody的结合,使用@RestController注解的类中的所有方法都会默认返回 JSON 或 XML 格式的数据。

  3. @PathVariable:用于从请求 URL 路径中提取变量值,并将其绑定到控制器方法的参数上,常用于 RESTful 风格的接口。例如getUserByIddeleteUser方法中,通过@PathVariable获取 URL 路径中的id参数。

  4. @RequestParam:用于将请求参数绑定到 Controller 方法的参数上,主要用于处理 GET、POST 等请求中的查询参数。例如:


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/users")
    public String getUsers(@RequestParam(defaultValue = "1") int page) {
        return "Get users on page: " + page;
    }
}
  1. @RestController:前面提到它是@Controller@ResponseBody的组合注解,用于创建 RESTful 风格的控制器,直接返回 JSON 或 XML 数据,而不是视图。

  2. @ControllerAdvice:用于定义全局的异常处理器和数据绑定等功能。通过@ControllerAdvice注解的类,可以对所有被@RequestMapping注解的方法进行统一处理。例如:


import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return new ResponseEntity<>("An error occurred: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  1. @ExceptionHandler:通常与@ControllerAdvice一起使用,用于定义异常处理方法,捕获并处理控制器中抛出的异常。如上述GlobalExceptionHandler类中的handleException方法,用于处理所有类型的异常。

  2. @ResponseStatus:用于指定方法返回时的 HTTP 状态码。例如:


import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @ResponseStatus(HttpStatus.CREATED)
    @PostMapping("/create")
    public String createUser() {
        return "User created successfully";
    }
}

(五)配置相关注解

  1. @ConfigurationProperties:用于将配置文件中的属性批量绑定到一个实体类上,比@Value更适合读取一组相关配置。例如,我们在application.yml中配置数据库连接信息:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password

然后创建一个DataSourceConfig类来绑定这些配置:


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceConfig {
    private String url;
    private String username;
    private String password;

    // 生成getter和setter方法
}
  1. @Value:用于注入单个配置项的值,通常从配置文件中获取。例如,我们在application.properties中定义一个属性app.name=MyApp,然后在代码中使用@Value注入:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController {
    @Value("${app.name}")
    private String appName;

    @GetMapping("/app/name")
    public String getAppName() {
        return appName;
    }
}
  1. @ConditionalOnProperty:根据配置文件中的属性动态加载 Bean。只有当指定的属性满足特定条件时,被该注解标注的 Bean 才会被创建。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;

@Configuration
public class CacheConfig {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    @ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
    public RedisCacheManager cacheManager() {
        return RedisCacheManager.builder(redisConnectionFactory).build();
    }
}
  1. @ConditionalOnClass:当类路径中存在指定的类时,被该注解标注的 Bean 才会被创建。例如,只有当项目中引入了RedisTemplate类时,才创建相关的 Bean:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

@Configuration
public class RedisConfig {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    @ConditionalOnClass(RedisTemplate.class)
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

(六)其他常用注解

  1. @Transactional:用于声明式事务管理,标注在类或方法上,指定事务的传播行为、隔离级别等。当一个方法被@Transactional注解修饰时,如果方法执行过程中出现异常,事务会自动回滚,保证数据的一致性。例如:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {
        // 模拟保存订单和扣减库存的操作
        orderDao.save(order);
        inventoryService.deductStock(order.getProductId(), order.getQuantity());
    }
}
  1. @Scheduled:用于声明一个方法为定时任务,按照指定的时间规则定时执行。例如,每天凌晨 2 点执行一次方法:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component## 实际案例分析


为了更直观地理解这些注解在实际开发中的应用,我们以一个简单的用户管理模块为例,来看看它们是如何协同工作的 。

### 项目结构概述
假设我们正在开发一个基于Spring Boot的用户管理系统,项目结构大致如下:

src ├── main │ ├── java │ │ └── com │ │ └── example │ │ ├── config │ │ │ └── DataSourceConfig.java// 数据源配置类 │ │ ├── controller │ │ │ └── UserController.java// 用户控制器类 │ │ ├── model │ │ │ └── User.java// 用户实体类 │ │ ├── repository │ │ │ └── UserRepository.java// 用户数据访问类 │ │ ├── service │ │ │ └── UserService.java// 用户服务类 │ │ └── Application.java// 启动类 │ └── resources │ ├── application.yml// 配置文件 │ └── static │ └── ... │ └── templates │ └── ... └── test └── java └── com └── example └── UserServiceTest.java// 用户服务测试类


### 关键注解应用
1. **启动类**:在`Application.java`中,使用`@SpringBootApplication`注解开启Spring Boot的自动配置和组件扫描功能:
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 数据源配置:在DataSourceConfig.java中,使用@Configuration标记为配置类,通过@Bean定义数据源 Bean,并使用@ConfigurationProperties将配置文件中的数据库连接信息绑定到数据源配置类中:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public HikariDataSource dataSource() {
        HikariConfig config = new HikariConfig();
        return new HikariDataSource(config);
    }
}
  1. 用户实体类:在User.java中,定义用户实体类,包含基本的用户信息字段:

public class User {
    private Long id;
    private String username;
    private String password;
    // 生成getter和setter方法
}
  1. 用户数据访问层:在UserRepository.java中,使用@Repository注解标记为数据访问组件,实现用户数据的数据库操作:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.model.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
  1. 用户服务层:在UserService.java中,使用@Service注解标记为服务组件,注入UserRepository,实现用户相关的业务逻辑。同时,在需要事务管理的方法上使用@Transactional注解:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.model.User;
import com.example.repository.UserRepository;

@Service
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional(readOnly = true)
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @Transactional
    public User saveUser(User user) {
        return userRepository.save(user);
    }
}
  1. 用户控制器层:在UserController.java中,使用@RestController注解标记为 RESTful 风格的控制器,处理用户相关的 HTTP 请求。通过@Autowired注入UserService,使用各种请求映射注解(如@GetMapping@PostMapping等)处理不同类型的请求,并使用@PathVariable@RequestBody等注解处理请求参数:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.example.model.User;
import com.example.service.UserService;

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return user != null? new ResponseEntity<>(user, HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    @PostMapping
    public ResponseEntity<User> saveUser(@RequestBody User user) {
        User savedUser = userService.saveUser(user);
        return new ResponseEntity<>(savedUser, HttpStatus.CREATED);
    }
}

通过这个简单的用户管理模块案例,我们可以看到各种 Spring Boot 注解在实际开发中的紧密协作。从项目的启动配置,到数据访问、业务逻辑处理,再到 Web 请求处理,注解贯穿了整个开发过程,大大简化了代码,提高了开发效率 。

总结与建议

通过对这 40 个 Spring Boot 常用注解的详细介绍,相信大家对 Spring Boot 注解体系有了更深入的理解。这些注解涵盖了 Spring Boot 开发的各个方面,从项目启动、Bean 管理、依赖注入,到 Web 开发、配置读取以及事务管理等,它们是 Spring Boot 开发不可或缺的工具 。

在实际开发中,合理使用注解可以大大提高开发效率,让我们的代码更加简洁、优雅。建议大家在日常开发中多尝试使用这些注解,并结合具体的业务场景,灵活运用它们的特性。同时,也要注意避免注解的滥用,保持代码的可读性和可维护性 。

如果你对 Spring Boot 注解还想进一步深入学习,可以研究一些注解的高级用法,比如自定义注解、注解与 AOP(面向切面编程)的结合使用等。这些高级技巧将帮助你更好地掌握 Spring Boot 框架,打造出更加健壮、高效的 Java 应用程序 。希望本文对你在 Spring Boot 开发中有所帮助,祝大家编码愉快!