Java注解本身仅提供元数据,不直接实现依赖注入;Spring通过AnnotationConfigApplicationContext等容器及AutowiredAnnotationBeanPostProcessor等后置处理器,在启动时解析注解并完成Bean创建、装配与生命周期管理。

Java 注解本身不直接实现依赖注入,它只是提供元数据;Spring 框架通过读取这些注解,在运行时(主要是容器启动阶段)解析并完成 Bean 的创建、装配和生命周期管理。核心在于 Spring 的 注解驱动容器(如 AnnotationConfigApplicationContext)与一系列内置的后置处理器(如 AutowiredAnnotationBeanPostProcessor)协同工作。
常用注入注解及其作用
Spring 提供了多个语义明确的注解,用于声明依赖关系:
-
@Autowired:按类型(byType)自动注入,支持字段、setter 方法、构造器。可配合
@Qualifier指定具体 Bean 名称,解决多实现冲突。 -
@Resource(JSR-250):默认按名称(byName)注入,名称来自字段名或
name属性;若找不到匹配名称,回退为按类型注入。 -
@Inject(JSR-330):类似
@Autowired,但标准更轻量,不支持required=false和延迟代理等 Spring 特有功能。 -
@Value:注入配置属性(如
@Value("${db.url}"))或字面量(如@Value("default-port")),需配合@PropertySource或外部配置文件使用。
启用注解驱动的关键配置
仅加注解不会生效,必须让 Spring 容器识别并处理它们:
- XML 方式:在 Spring 配置文件中添加
<context:annotation-config/>(启用注解解析)和<context:component-scan base-package="com.example"/>(扫描带@Component及其派生注解的类)。 - Java 配置方式:使用
@Configuration类 +@ComponentScan注解,并通过AnnotationConfigApplicationContext加载配置类。 - Spring Boot 默认已开启全部注解支持,无需额外配置,只需确保主类或配置类上有
@SpringBootApplication(它组合了@ComponentScan等)。
被注入类如何被 Spring 管理
只有被 Spring 容器“托管”的对象才能参与依赖注入。常见方式包括:
立即学习“Java免费学习笔记(深入)”;
- 使用
@Component或其语义化变体:@Service(业务层)、@Repository(数据层)、@Controller(Web 层)。Spring 扫描到后会将其注册为 Bean。 - 在
@Configuration类中用@Bean方法显式定义 Bean,方法返回值自动注册,参数可被自动注入(支持构造器注入)。 - 使用
@Scope控制作用域(如@Scope("prototype")),影响注入实例的生命周期和复用行为。
注入时机与常见注意事项
依赖注入发生在 Bean 实例化之后、初始化之前(即 InitializingBean.afterPropertiesSet() 或 @PostConstruct 方法前):
- 构造器注入最安全,能保证依赖不为 null,且天然支持不可变对象和循环依赖检测(Spring 4.3+ 对单构造器场景自动推导)。
- 字段注入简洁但破坏封装性,无法在测试中手动传入 Mock 对象;setter 注入灵活但需确保 setter 被调用。
- 避免在
@PostConstruct或初始化方法中使用尚未注入的字段(尤其是字段注入时未加@Autowired(required = false)且依赖缺失)。 - 循环依赖(A 依赖 B,B 又依赖 A)在单例 Bean 中可通过三级缓存解决,但推荐重构代码消除依赖环。
不复杂但容易忽略:注解是“声明”,Spring 容器才是“执行者”。理解容器如何扫描、注册、解析、装配,比死记注解用法更重要。


















