
Spring 负责注入的注解详解Spring 的注入注解分为两大体系Spring 自有注解Autowired、Qualifier、Primary、Value和JSR 标准注解Resource、Inject、Named。它们共同解决同一个问题把容器中的 Bean 或配置值注入到目标对象中。一、注入注解总览注解来源匹配方式支持位置特有属性AutowiredSpring先按类型再按名称字段、构造器、Setter、参数requiredQualifierSpring按名称字段、构造器、Setter、参数valuePrimarySpring标记首选类、方法—ValueSpring按配置键字段、构造器、Setter、参数valueResourceJSR-250先按名称再按类型字段、Settername、typeInjectJSR-330按类型字段、构造器、方法—NamedJSR-330按名称类、字段、参数value二、AutowiredSpring 最核心的注入注解默认按类型匹配。2.1 三种注入位置构造器注入推荐ServicepublicclassUserService{privatefinalUserDaouserDao;publicUserService(UserDaouserDao){this.userDaouserDao;}}类只有一个构造方法时Autowired可以省略。字段注入ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}Setter 注入ServicepublicclassUserService{privateUserDaouserDao;AutowiredpublicvoidsetUserDao(UserDaouserDao){this.userDaouserDao;}}2.2 匹配规则按类型查找容器中的 Bean。找到多个同类型 Bean 时按字段名或参数名匹配 Bean 名称。仍无法确定时尝试Primary标记的 Bean。最后用Qualifier指定的名称匹配。2.3 required 属性Autowired(requiredfalse)privateUserDaouserDao;// 找不到时注入 null不报错默认required true找不到匹配 Bean 时抛NoSuchBeanDefinitionException。2.4 底层处理AutowiredAnnotationBeanPostProcessor处理Autowired、Value、Inject。它在postProcessProperties()中扫描字段和方法通过DefaultListableBeanFactory.resolveDependency()解析依赖并注入。三、Qualifier配合Autowired使用在同类型多 Bean 时按名称指定。ServicepublicclassOrderService{AutowiredQualifier(aliPayService)privatePaymentServicepaymentService;}构造器参数上也可以使用publicOrderService(Qualifier(aliPayService)PaymentServicepaymentService){this.paymentServicepaymentService;}Qualifier的优先级高于Primary。四、Primary同类型多 Bean 时标记其中一个为首选解决Autowired的歧义。ServicePrimarypublicclassAliPayServiceimplementsPaymentService{}ServicepublicclassWechatPayServiceimplementsPaymentService{}ServicepublicclassOrderService{AutowiredprivatePaymentServicepaymentService;// 注入 AliPayService}Primary可以标注在类上也可以标注在Bean方法上BeanPrimarypublicDataSourceprimaryDataSource(){...}五、Value注入简单类型和配置值不涉及 Bean 之间的依赖。ComponentpublicclassAppConfig{Value(${app.name})privateStringappName;Value(${app.timeout:30})privateinttimeout;Value(${app.debug:false})privatebooleandebug;Value(#{${app.timeout} * 1000})privateinttimeoutInMillis;}${key:default}设置默认值#{}使用 SpEL 表达式。Value的底层也是AutowiredAnnotationBeanPostProcessor处理与Autowired共用同一条注入链路。六、ResourceJSR-250 标准注解由 JDK 提供Spring 支持。默认按名称注入找不到再按类型。ServicepublicclassUserService{Resource(nameuserDaoImpl)privateUserDaouserDao;}不指定name时默认使用字段名作为 Bean 名称ResourceprivateUserDaouserDao;// 按名称 userDao 查找Resource 与 Autowired 的区别对比维度AutowiredResource来源SpringJSR-250JDK匹配方式先按类型再按名称先按名称再按类型required 属性支持不支持构造器注入支持不支持Primary 支持支持不支持适用场景Spring 生态通用按名称注入、非 Spring 环境Resource由CommonAnnotationBeanPostProcessor处理。七、Inject 和 NamedJSR-330 标准注解需要引入javax.inject或jakarta.inject依赖。dependencygroupIdjakarta.inject/groupIdartifactIdjakarta.inject-api/artifactIdversion2.0.1/version/dependencyInject按类型注入语义与Autowired基本一致但没有required属性。ServicepublicclassUserService{InjectprivateUserDaouserDao;}Named配合Inject按名称指定ServicepublicclassOrderService{InjectNamed(aliPayService)privatePaymentServicepaymentService;}也可以标注在类上指定 Bean 名称Named(aliPayService)publicclassAliPayServiceimplementsPaymentService{}Inject和Named同样由AutowiredAnnotationBeanPostProcessor处理Spring 对它们提供了完整支持。八、注入注解的底层处理链所有注入注解最终都汇聚到两个BeanPostProcessorAutowiredAnnotationBeanPostProcessor ├── Autowired ├── Value └── Inject CommonAnnotationBeanPostProcessor ├── Resource ├── PostConstruct └── PreDestroy处理时机在 Bean 生命周期的属性填充阶段populateBean()由postProcessProperties()方法完成注入。简化流程// AutowiredAnnotationBeanPostProcessorpublicPropertyValuespostProcessProperties(PropertyValuespvs,Objectbean,StringbeanName){// 1. 扫描字段和方法上的 Autowired、Value、InjectInjectionMetadatametadatafindAutowiringMetadata(beanName,bean.getClass(),pvs);// 2. 逐个解析依赖并注入metadata.inject(bean,beanName,pvs);returnpvs;}metadata.inject()内部通过DefaultListableBeanFactory.resolveDependency()查找匹配的 Bean再通过反射设置字段值或调用方法。九、四种注入方式对比对比维度构造器注入Setter 注入字段注入方法参数注入推荐程度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐依赖不可变✅ final❌❌✅空指针风险无有有无单元测试容易中等困难容易循环依赖不支持支持支持不支持Spring 官方推荐✅⚠️❌✅Spring 官方推荐构造器注入原因依赖不可变用final修饰对象创建时依赖完全就绪便于单元测试直接传入 Mock依赖过多时构造方法参数过长能及时暴露设计问题十、常见问题1. 同类型多 Bean 注入失败NoUniqueBeanDefinitionException: expected single matching bean but found 2解决方案用Qualifier指定名称或用Primary标记首选。2. Autowired 注入 null检查类是否被 Spring 管理检查包是否在ComponentScan范围内检查是否设置了required false3. 构造器注入循环依赖ServicepublicclassAService{publicAService(BServiceb){}}ServicepublicclassBService{publicBService(AServicea){}}启动时报BeanCurrentlyInCreationException。构造器注入无法解决循环依赖应通过重构消除或改用字段注入。4. Resource 找不到 BeanResource默认按名称匹配字段名必须与 Bean 名称一致。不一致时需指定name。5. Value 注入失败Could not resolve placeholder app.name检查配置文件中是否有对应的键或设置默认值${app.name:default}。十一、总结维度核心要点核心注解Autowired按类型、Resource按名称、Inject按类型辅助注解Qualifier指定名称、Primary标记首选配置注入Value简单类型和配置值推荐方式构造器注入底层处理AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor处理时机Bean 生命周期的属性填充阶段匹配优先级QualifierPrimary 按类型 按名称Spring 的注入注解体系围绕“按类型”和“按名称”两条主线展开。Autowired和Inject默认按类型Resource和Named默认按名称Qualifier和Primary用于解决歧义。理解每个注解的匹配规则和底层处理机制能帮你在实际开发中做出正确的选择避免注入失败和循环依赖等问题。