在 Spring Boot 项目开发中,合理使用注解可以极大地简化配置,提高开发效率。本文将对 Spring Boot 中常用的注解进行分类整理,并结合实际案例进行讲解,帮助开发者更好地理解和运用。我们经常遇到的问题是,各种注解用法容易混淆,不知道该在什么场景下使用哪个注解。例如,@Controller 和 @RestController 的区别,@Autowired 和 @Resource 的选择等。本文旨在解决这些痛点,提供一个全面的 Spring Boot 注解参考。
核心注解
控制层注解
@Controller: 用于标记一个类作为 Spring MVC 的控制器,处理 HTTP 请求。
@Controller public class HelloController { @RequestMapping("/hello") public String hello(Model model) { model.addAttribute("message", "Hello, Spring Boot!"); return "hello"; // 返回视图名称 } }@RestController: 相当于
@Controller+@ResponseBody,用于创建 RESTful API,直接返回数据,而非视图。@RestController public class ApiController { @GetMapping("/api/data") public Map<String, String> getData() { Map<String, String> data = new HashMap<>(); data.put("key", "value"); return data; // 返回 JSON 数据 } }@RequestMapping: 用于映射 HTTP 请求到控制器方法。

@RequestMapping(value = "/users", method = RequestMethod.GET) public List<User> getUsers() { // 处理 GET 请求 return userService.getAllUsers(); }
组件注解
@Component: 泛型组件注解,用于标记一个类作为 Spring 的组件,可以被 Spring 容器管理。
@Service: 用于标记一个类作为服务组件,通常用于业务逻辑层的实现。
@Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; // 实现 UserService 接口的方法 }@Repository: 用于标记一个类作为数据访问组件,通常用于数据访问层的实现。

@Repository public interface UserRepository extends JpaRepository<User, Long> { // 定义数据访问方法 }@Configuration: 用于标记一个类作为配置类,通常用于定义 Spring 的 Bean。
@Configuration public class AppConfig { @Bean public DataSource dataSource() { // 配置数据源 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("password"); return dataSource; } }@Bean: 用于将一个方法声明为一个 Bean,交由 Spring 容器管理。
@Bean public RestTemplate restTemplate() { return new RestTemplate(); }
依赖注入注解
@Autowired: 用于自动注入依赖,根据类型进行匹配。

@Autowired private UserService userService;@Resource: 用于自动注入依赖,可以根据名称或类型进行匹配,是 JSR-250 规范的一部分。 如果同时指定 name 和 type,则从 Spring 上下文中找到唯一匹配的 Bean 进行装配,找不到则抛出异常。 如果只指定了 name,则从 Spring 上下文中查找名称(id)匹配的 Bean 进行装配,找不到则抛出异常。 如果只指定了 type,则从 Spring 上下文中找到类型匹配的唯一 Bean 进行装配,找不到或者找到多个,都会抛出异常。
@Resource(name = "userServiceImpl") private UserService userService;@Value: 用于注入配置文件中的值。
@Value("${app.name}") private String appName;
其他常用注解
@PostConstruct: 用于标记一个方法在 Bean 初始化完成后执行,JSR-250 规范。

@PostConstruct public void init() { // 初始化操作 System.out.println("Bean 初始化完成"); }@PreDestroy: 用于标记一个方法在 Bean 销毁之前执行,JSR-250 规范。
@PreDestroy public void destroy() { // 清理操作 System.out.println("Bean 销毁"); }@Scope: 用于定义 Bean 的作用域,例如 singleton(单例,默认)、prototype(原型)、request、session 等。
@Scope("prototype") @Bean public User user() { return new User(); }@ConditionalOnProperty: 根据配置文件中的属性值来决定是否创建 Bean。
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true") @Bean public FeatureService featureService() { return new FeatureServiceImpl(); }
实战避坑经验总结
- @Autowired 的坑: 如果 Spring 容器中存在多个相同类型的 Bean,
@Autowired会抛出NoUniqueBeanDefinitionException异常。 解决方法是使用@Qualifier注解指定 Bean 的名称,或者使用@Resource注解,并指定name属性。 - @Transactional 的坑:
@Transactional注解默认只对 RuntimeException 进行回滚。 如果需要对 Checked Exception 进行回滚,需要显式指定rollbackFor属性。 另外,如果事务方法内部调用了同一个类中的另一个事务方法,可能会导致事务失效。 解决方法是将内部方法拆分到另一个类中,或者使用TransactionTemplate手动管理事务。 - 配置文件的坑: 在 Spring Boot 项目中,配置文件(
application.properties或application.yml)的加载顺序很重要。 优先级从高到低依次为:命令行参数、来自java:comp/env的 JNDI 属性、Java 系统属性、操作系统环境变量、随机生成的带random.*前缀的属性、JAR 包外部的 application-{profile}.properties 或 application.yml、JAR 包内部的 application-{profile}.properties 或 application.yml、JAR 包外部的 application.properties 或 application.yml、JAR 包内部的 application.properties 或 application.yml。 错误的配置可能会导致属性值被覆盖。
此外,在生产环境中,通常会使用 Nginx 作为反向代理服务器,实现负载均衡和高可用。Nginx 可以根据不同的策略(例如轮询、IP Hash、URL Hash)将请求分发到不同的后端服务器。 在配置 Nginx 时,需要注意并发连接数、Keep-Alive 超时时间等参数,以避免性能瓶颈。 也可以使用宝塔面板等工具简化 Nginx 的配置和管理。
理解并熟练运用 Spring Boot 常用注解,能够有效地提高开发效率和代码质量。希望本文能够帮助读者更好地掌握 Spring Boot 注解的使用,避免常见的坑,并在实际项目中灵活应用。
冠军资讯
程序员石头