Spring为什么Autowired注入的是接口

本文详细介绍了Spring框架如何进行依赖注入,包括当存在单一实现时自动装配的机制,以及当存在多个实现时如何通过@Qualifier注解指定具体实现的方法。此外还讨论了为什么建议在接口而非实现类上使用@Autowired。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 1.Spring怎么知道注入哪个实现?  
  2. As long as there is only a single implementation of the interface and that implementation is annotated with @Component with Spring’s component scan enabled, Spring framework can find out the (interface, implementation) pair. If component scan is not enabled, then you have to define the bean explicitly in your application-config.xml (or equivalent spring configuration file).   
  3. 如果Spring配置了component scan,并且要注入的接口只有一个实现的话,那么spring框架可以自动将interface于实现组装起来。如果没有配置component scan,那么你必须在application-config.xml(或等同的配置文件)定义这个bean。  
  4.   
  5.   
  6. 2.需要@Qualifier@Resource注解吗?  
  7. Once you have more than one implementation, then you need to qualify each of them and during auto-wiring, you would need to use the @Qualifier annotation to inject the right implementation, along with @Autowired annotation. If you are using @Resource (J2EE semantics), then you should specify the bean name using the name attribute of this annotation.   
  8. 一旦一个接口有多个实现,那么就需要每个特殊化识别并且在自动装载过程中使用@Qualifier@Autowired一起使用来标明。如果是使用@Resource注解,那么你应该使用resource中属性名称来标注@Autowired.  
  9.   
  10.   
  11. 3.为什么@Autowired使用在interface上而不是实现类上?  
  12. Firstly, it is always a good practice to code to interfaces in general. Secondly, in case of spring, you can inject any implementation at runtime. A typical use case is to inject mock implementation during testing stage.   
  13. 首先,一般使用接口是很常用并且有益的变成技术。其次,在spring中,你可以在运行过程中注入各种实现。一个很经典的情况就是在测试阶段,注入模拟的实现类。   
  14. interface IA   
  15. {   
  16. public void someFunction();   
  17. }  
  18.   
  19.   
  20. class B implements IA   
  21. {   
  22. public void someFunction()   
  23. {   
  24. //busy code block   
  25. }   
  26. public void someBfunc()   
  27. {   
  28. //doing b things   
  29. }   
  30. }  
  31.   
  32.   
  33. class C implements IA   
  34. {   
  35. public void someFunction()   
  36. {   
  37. //busy code block   
  38. }   
  39. public void someCfunc()   
  40. {   
  41. //doing C things   
  42. }   
  43. }  
  44.   
  45.   
  46. `class MyRunner   
  47. {   
  48. @Autowire   
  49. @Qualifier(“b”)  
  50. IA worker;  
  51.   
  52.   
  53. ....  
  54. worker.someFunction();  
  55. }`   
  56. Your bean configuration should look like this:  
  57.   
  58.   
  59.   
  60.   
  61.   
  62. Alternatively, if you enabled component scan on the package where these are present, then you should qualify each class with @Component as follows:  
  63.   
  64.   
  65. interface IA   
  66. {   
  67. public void someFunction();   
  68. }  
  69.   
  70.   
  71. @Component(value="b")   
  72. class B implements IA   
  73. {   
  74. public void someFunction()   
  75. {   
  76. //busy code block   
  77. }   
  78. public void someBfunc()   
  79. {   
  80. //doing b things   
  81. }   
  82. }  
  83.   
  84.   
  85. @Component(value="c")   
  86. class C implements IA   
  87. {   
  88. public void someFunction()   
  89. {   
  90. //busy code block   
  91. }   
  92. public void someCfunc()   
  93. {   
  94. //doing C things   
  95. }   
  96. }  
  97.   
  98.   
  99. `@Component   
  100. class MyRunner   
  101. {   
  102. @Autowire   
  103. @Qualifier(“b”)  
  104. IA worker;  
  105.   
  106.   
  107. ....  
  108. worker.someFunction();  
  109. }`  
### 解析 Spring 中 `@Autowired` 注解注入接口失败的原因 当在 Spring 应用程序中使用 `@Autowired` 注入接口时出现问题,通常是因为以下几个常见原因: #### 接口实现类缺失或未被扫描到 如果某个接口没有任何具体的实现类,或者这些实现类不在组件扫描路径内,那么 Spring 将无法找到合适的 Bean 进行注入。确保所有的实现类都带有适当注解(如 `@Component`, `@Service` 或者其他自定义的 stereotype 注解),并且位于应用程序上下文能够扫描到的位置。 #### 多个相同类型的 Bean 存在冲突 如果有多个实现了同一接口的不同 Bean 被注册到了容器里而没有指定具体哪一个要用于依赖注入的话,也会造成注入错误。此时可以通过给定限定符(`@Qualifier`)来指明特定的名字或者是通过设置主要候选(`primary=true`)的方式来解决问题[^1]。 ```java @Service("specificServiceImpl") public class SpecificServiceImpl implements MyInterface { // Implementation details... } ``` ```java @Autowired @Qualifier("specificServiceImpl") private MyInterface myInterface; ``` #### 配置排除项影响了自动装配过程 某些情况下项目中的配置可能会无意间阻止了一些必要的 Bean 的创建。例如,在应用主类上使用了类似于 `exclude={DataSourceAutoConfiguration.class}` 的参数可以防止默认的数据源配置加载,这可能间接导致与数据库相关的组件未能正常初始化并进而引发关联对象注入异常的情况发生[^2]。 #### 使用非标准的方式获取Bean实例 对于那些确实难以通过常规手段完成注入操作的服务来说,还可以考虑采用编程式的查找方法作为替代方案之一——即利用 `ApplicationContext.getBean()` 方法按需检索目标 Bean 实例[^3]: ```java @Autowired private ApplicationContext context; @Bean public SomeType someMethod() { return (SomeType)context.getBean("someTypeName"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值