Spring Spring Boot 常用注解详解:生命周期、懒加载、优先加载与实用技巧

📅 2026/7/11 15:36:35 👁️ 阅读次数 📝 编程学习
Spring  Spring Boot 常用注解详解:生命周期、懒加载、优先加载与实用技巧

Spring & Spring Boot 常用注解详解:生命周期、懒加载、优先加载与实用技巧

前言

在 Spring 和 Spring Boot 开发中,注解几乎是“每天必打交道”的伙伴。它们像魔法一样,可以帮你声明 Bean、管理依赖、控制加载顺序、处理事务、配置环境……但注解多了也容易混淆。本教程将按功能模块,带你系统梳理 Spring 生态中最常用的注解,尤其会重点讲解生命周期、懒加载和优先加载相关的那些“容易踩坑”的注解。全文配合示例,希望对你的日常开发有所助益。


目录

  1. 核心组件注解——声明一个 Bean
  2. 配置与注册 Bean
  3. 依赖注入(DI)注解
  4. 生命周期注解(⭐重点)
  5. 懒加载与优先加载(⭐重点)
  6. 条件装配与环境配置
  7. Spring Boot 核心注解
  8. 其他高频实用注解
  9. 总结

1. 核心组件注解——声明一个 Bean

想让一个类被 Spring 管理,最简单的办法就是给它贴上对应的“标签”。

注解作用说明
@Component通用的组件注解,标注后类会被 Spring 扫描并加入容器最基础的 Bean 注解
@Service标记服务层组件语义更明确,本质同@Component
@Repository标记持久层组件额外自动转换数据库异常为 Spring 的DataAccessException
@Controller/@RestController标记控制器@RestController=@Controller+@ResponseBody,返回 JSON 时常用

示例:

@ServicepublicclassUserServiceImplimplementsUserService{// ...}

📌提示@Repository其实还承担了异常翻译功能,如果直接使用@Component标注 DAO 类,数据库异常不会自动转换成 Spring 的异常体系。


2. 配置与注册 Bean

当我们不能直接修改类(比如第三方库)或需要更灵活的 Bean 定义时,就用到下面这些注解。

注解作用常用场景
@Configuration声明一个配置类,内部可以用@Bean方法定义 Bean代替 XML 配置
@Bean方法级别,返回的对象会被纳入 Spring 容器自定义组装 Bean,可通过initMethod/destroyMethod指定回调
@ComponentScan指定扫描包路径,自动发现组件自定义扫描哪些包
@Import快速导入其他配置类或普通类模块化配置

示例:

@ConfigurationpublicclassAppConfig{@Bean(name="dataSource",initMethod="start",destroyMethod="close")publicDataSourcedataSource(){returnnewBasicDataSource();}}

3. 依赖注入(DI)注解

一个 Bean 想用另一个 Bean,只需要“告诉” Spring 你在哪里需要它。

注解作用
@Autowired按类型自动注入,可标注在构造器、字段、setter 方法上
@Qualifier配合@Autowired,当有多个实现时按名称精确注入
@Primary当存在多个同类型 Bean 时,标注一个为首选
@Value注入外部属性值(如${server.port})或 SpEL 表达式
@Resource按名称注入(JSR-250),不常用但存在

示例:

@Autowired@Qualifier("userJdbcRepository")privateUserRepositoryuserRepository;

⚠️注意:当存在多个同一接口的实现类时,@Autowired会报错,此时要么使用@Qualifier,要么用@Primary指定默认。


4. 生命周期注解(⭐重点)

这是很多初学者容易忽略,但实际开发非常重要的部分。典型场景:初始化连接池、注册资源、销毁时清理线程等。

4.1@PostConstruct@PreDestroy

  • 来源javax.annotation(现 Jakarta EE)
  • 作用
    • @PostConstruct:在 Bean 的依赖注入完成之后,正式可用之前执行
    • @PreDestroy:容器销毁该 Bean之前执行清理工作(仅对单例有效)

使用示例:

@ComponentpublicclassCacheManager{@PostConstructpublicvoidinit(){// 初始化连接池、预加载缓存等System.out.println("CacheManager 初始化完成");}@PreDestroypublicvoidcleanup(){// 释放资源、关闭连接等System.out.println("CacheManager 即将销毁,执行清理");}}

执行顺序:
构造方法 → 依赖注入(@Autowired)→@PostConstruct→ Bean 就绪

4.2@BeaninitMethoddestroyMethod

如果类不是你自己写的,没法加@PostConstruct注解,可以在@Bean中指定方法名。

@Bean(initMethod="start",destroyMethod="stop")publicThirdPartyServicethirdPartyService(){returnnewThirdPartyService();}
  • destroyMethod默认推断closeshutdown方法,若要关闭推断可设为空字符串destroyMethod=""

4.3 实现InitializingBeanDisposableBean接口(了解即可)

  • InitializingBeanafterPropertiesSet()等同于@PostConstruct
  • DisposableBeandestroy()等同于@PreDestroy

✅ 建议:优先使用@PostConstruct/@PreDestroy,它们不与 Spring 强耦合,代码更干净。

4.4@Scope对生命周期的影响

  • @Scope("singleton"):默认,容器初始化时就创建(除非被@Lazy延迟),完整生命周期由 Spring 管理。
  • @Scope("prototype"):每次获取都会新建,Spring 只负责创建,不负责销毁,因此@PreDestroy不会回调。

5. 懒加载与优先加载(⭐重点)

5.1@Lazy—— 懒加载

  • 作用:让单例 Bean 的初始化推迟到第一次被调用时,而不是容器启动时。
  • 可用于@Component@Bean@Autowired

示例:

@Service@LazypublicclassReportService{publicReportService(){System.out.println("ReportService 被实例化");}}

效果

  • 容器启动时不会创建ReportService,第一次调用它的方法时才会触发构造。
  • 加快应用启动速度,适用于那些启动时不一定用到的重型服务。

注入点使用@Lazy

@Autowired@LazyprivateHeavyServiceheavyService;

此时注入的是一个代理对象,直到真正调用代理方法时才会从容器获取目标 Bean。

5.2@DependsOn—— 依赖优先

  • 作用:强制指定当前 Bean 必须在指定的 Bean初始化完成之后才能创建。
  • 适用场景:虽然没有直接注入,但存在静态注册或隐式依赖(例如 A 的静态代码块依赖 B 准备好)。

示例:

@Component@DependsOn("eventLogger")publicclassEventService{...}

这样EventService无论如何都会等到eventLoggerBean 完全初始化后才开始创建。

5.3@Order@Priority—— 控制顺序

  • @Orderorg.springframework.core.annotation.Order):常用于同一接口的多个实现,控制它们作为List注入时的排序,值越小优先级越高
  • @Priority:JSR-250 标准,功能相似,也可用于选择首选 Bean。

常见用途:过滤器、拦截器、事件监听器的顺序。

@Component@Order(1)publicclassFirstFilterimplementsFilter{...}@Component@Order(2)publicclassSecondFilterimplementsFilter{...}

5.4@Primary—— 优先选择

  • 当存在多个同类型 Bean 时,标注@Primary的 Bean 会作为@Autowired的默认选择。
  • @Qualifier的精确选择优先级高于@Primary

6. 条件装配与环境配置

不同环境需要不同的 Bean?想让某些 Bean 只在特定条件下生效?下面这些注解帮你优雅实现。

注解作用
@Profile根据激活的环境(application-{profile}.yml)决定是否加载 Bean
@ConditionalOnClass类路径下存在指定类时才生效(Spring Boot 自动配置核心)
@ConditionalOnMissingBean容器中缺少指定 Bean 时才会创建
@ConditionalOnProperty根据配置项的值(prefix.enabled=true)决定是否启用
@PropertySource加载指定的.properties文件
@ConfigurationProperties将配置前缀的属性批量绑定到类字段,需配合@EnableConfigurationProperties

示例:

@Configuration@Profile("dev")publicclassDevDataSourceConfig{...}@Bean@ConditionalOnMissingBeanpublicCacheManagercacheManager(){returnnewConcurrentMapCacheManager();}

7. Spring Boot 核心注解

注解等价/作用
@SpringBootApplication@Configuration+@EnableAutoConfiguration+@ComponentScan
@EnableAutoConfiguration触发 Spring Boot 的自动配置机制
@RestControllerAdvice全局异常处理 +@ResponseBody,常配合@ExceptionHandler
@SpringBootTest集成测试时加载完整 ApplicationContext

Spring Boot 主类只要一个@SpringBootApplication就能启动自动扫描和自动配置。


8. 其他高频实用注解

Web 层

@GetMapping("/users/{id}")publicUsergetUser(@PathVariableLongid,@RequestParam(required=false)Stringname,@RequestBodyUseruser){...}

常用搭配:@RequestMapping@PostMapping@PutMapping@DeleteMapping@RequestHeader@CookieValue@CrossOrigin

异步与调度

  • @Async:方法异步执行,需在主类添加@EnableAsync
  • @Scheduled(fixedRate = 5000):定时任务,需添加@EnableScheduling

事务与缓存

  • @Transactional:声明式事务,可用于类或方法。
  • @Cacheable(value = "users", key = "#id")/@CacheEvict/@CachePut:配合缓存抽象(如 Redis)。

参数校验

  • @Valid/@Validated:触发参数校验。
  • 配合@NotNull@NotBlank@Size等 JSR-303 注解。

示例:

@PostMappingpublicResultcreate(@Valid@RequestBodyUseruser){// ...}

9. 总结

速查表帮你快速回忆:

类别关键注解一句话说明
生命周期@PostConstruct@PreDestroy@Bean(initMethod)控制 Bean 的初始化和销毁逻辑
懒加载@Lazy延迟创建直到首次使用
优先/顺序@DependsOn@Order@Priority@Primary控制 Bean 初始化顺序、注入优先级和排序
依赖注入@Autowired@Qualifier@Value自动装配成员
组件声明@Component@Service@Repository@Controller声明 Bean 并加入容器
条件装配@Profile@ConditionalOnClass按条件决定是否加载 Bean
配置绑定@ConfigurationProperties将配置批量绑定到对象
核心入口@SpringBootApplicationSpring Boot 主类必备

掌握这些注解后,你会发现写 Spring 项目就像拼积木,干净又灵活。不妨收藏本教程,在遇到疑惑时快速查阅。如果还想深入了解某一类注解(比如事务传播机制、异步配置、缓存策略),欢迎在评论区留言,我会根据大家的反馈继续更新。