吐血整理!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 定义与管理注解
@Component:这是一个通用的组件注解,用于将一个类标识为 Spring 管理的组件(Bean),Spring 容器会自动扫描并注册带有该注解的类。比如我们定义一个工具类Utils,可以使用@Component注解将其纳入 Spring 容器管理:
import org.springframework.stereotype.Component;
@Component
public class Utils {
public String sayHello() {
return "Hello from Utils";
}
}
@Service:专门用于标记服务层组件,是@Component的特化版本,语义更加明确,用于表示业务逻辑服务。例如,我们有一个用户服务类UserService:
import org.springframework.stereotype.Service;
@Service
public class UserService {
public String getUserInfo() {
return "User information";
}
}
@Repository:用于标记数据访问层组件,也是@Component的特化注解,它除了将类标识为组件外,还能自动处理数据库操作的异常。以用户数据访问类UserRepository为例:
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public void saveUser() {
// 模拟保存用户到数据库的操作
}
}
@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;
}
}
@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);
}
}
-
@Configuration:标记一个类为配置类,替代传统的 XML 配置文件,类中可以通过@Bean注解定义自定义的 Bean。如上述的DataSourceConfig类,通过@Configuration标记为配置类,然后在其中定义了dataSourceBean。 -
@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();
}
}
@Primary:当存在多个相同类型的 Bean 时,使用@Primary注解可以指定一个优先被注入的 Bean。假设我们有两个实现了UserService接口的类UserServiceA和UserServiceB,并且希望在注入时优先使用UserServiceA,可以这样标注:
import org.springframework.stereotype.Service;
@Service
@Primary
public class UserServiceA implements UserService {
@Override
public void getUserInfo() {
System.out.println("User Service A");
}
}
@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;
}
}
@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");
}
}
(三)依赖注入注解
@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();
}
}
@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();
}
}
@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 开发注解
@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";
}
}
@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;
}
}
-
@RequestBody:用于将 HTTP 请求体的内容(如 JSON、XML)转换为 Java 对象,通常用于接收前端传递的数据,标注在方法的参数上。比如上述addUser和updateUser方法中,通过@RequestBody接收前端传递的User对象。 -
@ResponseBody:将方法的返回值转换为指定格式(如 JSON、XML)作为 HTTP 响应的内容返回给客户端,通常与@RequestMapping或@GetMapping等注解一起使用在方法上。而@RestController注解实际上是@Controller和@ResponseBody的结合,使用@RestController注解的类中的所有方法都会默认返回 JSON 或 XML 格式的数据。 -
@PathVariable:用于从请求 URL 路径中提取变量值,并将其绑定到控制器方法的参数上,常用于 RESTful 风格的接口。例如getUserById和deleteUser方法中,通过@PathVariable获取 URL 路径中的id参数。 -
@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;
}
}
-
@RestController:前面提到它是@Controller和@ResponseBody的组合注解,用于创建 RESTful 风格的控制器,直接返回 JSON 或 XML 数据,而不是视图。 -
@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);
}
}
-
@ExceptionHandler:通常与@ControllerAdvice一起使用,用于定义异常处理方法,捕获并处理控制器中抛出的异常。如上述GlobalExceptionHandler类中的handleException方法,用于处理所有类型的异常。 -
@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";
}
}
(五)配置相关注解
@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方法
}
@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;
}
}
@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();
}
}
@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;
}
}
(六)其他常用注解
@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());
}
}
@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);
}
}
- 数据源配置:在
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);
}
}
- 用户实体类:在
User.java中,定义用户实体类,包含基本的用户信息字段:
public class User {
private Long id;
private String username;
private String password;
// 生成getter和setter方法
}
- 用户数据访问层:在
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> {
}
- 用户服务层:在
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);
}
}
- 用户控制器层:在
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 开发中有所帮助,祝大家编码愉快!