@@ -232,37 +232,40 @@ Spring 内置的 `@Autowired` 以及 JDK 内置的 `@Resource` 和 `@Inject` 都
232232
233233### @Autowired   和 @Resource   的区别是什么? 
234234
235- ` Autowired `  属于  Spring 内置的注解,默认的注入方式为 ` byType ` (根据类型进行匹配),也就是说会优先根据接口类型去匹配并注入  Bean (接口的实现类) 。
235+ ` @ Autowired`  是  Spring 内置的注解,默认注入逻辑为 ** 先按类型(byType)匹配,若存在多个同类型  Bean,则再尝试按名称(byName)筛选 ** 。
236236
237- ** 这会有什么问题呢? **  当一个接口存在多个实现类的话, ` byType ` 这种方式就无法正确注入对象了,因为这个时候 Spring 会同时找到多个满足条件的选择,默认情况下它自己不知道选择哪一个。 
237+ 具体来说: 
238238
239- 这种情况下,注入方式会变为 ` byName ` (根据名称进行匹配),这个名称通常就是类名(首字母小写)。就比如说下面代码中的 ` smsService `  就是我这里所说的名称,这样应该比较好理解了吧。
239+ 1 .  优先根据接口 / 类的类型在 Spring 容器中查找匹配的 Bean。若只找到一个符合类型的 Bean,直接注入,无需考虑名称;
240+ 2 .  若找到多个同类型的 Bean(例如一个接口有多个实现类),则会尝试通过** 属性名或参数名** 与 Bean 的名称进行匹配(默认 Bean 名称为类名首字母小写,除非通过 ` @Bean(name = "...") `  或 ` @Component("...") `  显式指定)。
240241
241- ``` java 
242- //  smsService 就是我们上面所说的名称
243- @Autowired 
244- private  SmsService  smsService;
245- ``` 
242+ 当一个接口存在多个实现类时:
243+ 
244+ -  若属性名与某个 Bean 的名称一致,则注入该 Bean;
245+ -  若属性名与所有 Bean 名称都不匹配,会抛出 ` NoUniqueBeanDefinitionException ` ,此时需要通过 ` @Qualifier `  显式指定要注入的 Bean 名称。
246246
247- 举个例子, ` SmsService `  接口有两个实现类:  ` SmsServiceImpl1 ` 和  ` SmsServiceImpl2 ` ,且它们都已经被 Spring 容器所管理。 
247+ 举例说明: 
248248
249249``` java 
250- //  报错,byName 和 byType 都无法匹配到 bean
250+ //  SmsService 接口有两个实现类:SmsServiceImpl1、SmsServiceImpl2(均被 Spring 管理)
251+ 
252+ //  报错:byType 匹配到多个 Bean,且属性名 "smsService" 与两个实现类的默认名称(smsServiceImpl1、smsServiceImpl2)都不匹配
251253@Autowired 
252254private  SmsService  smsService;
253- //  正确注入 SmsServiceImpl1 对象对应的 bean
255+ 
256+ //  正确:属性名 "smsServiceImpl1" 与实现类 SmsServiceImpl1 的默认名称匹配
254257@Autowired 
255258private  SmsService  smsServiceImpl1;
256- //  正确注入  SmsServiceImpl1 对象对应的 bean 
257- //  smsServiceImpl1 就是我们上面所说的名称 
259+ 
260+ //  正确:通过 @Qualifier 显式指定 Bean 名称 "smsServiceImpl1" 
258261@Autowired 
259262@Qualifier (value  =  " smsServiceImpl1"  )
260263private  SmsService  smsService;
261264``` 
262265
263- 我们还是建议通过 ` @Qualifier `  注解来显式指定名称而不是依赖变量的名称。
266+ 实际开发实践中, 我们还是建议通过 ` @Qualifier `  注解来显式指定名称而不是依赖变量的名称。
264267
265- ` @Resource ` 属于 JDK 提供的注解,默认注入方式为  ` byName ` 。如果无法通过名称匹配到对应的  Bean 的话,注入方式会变为 ` byType ` 。
268+ ` @Resource ` 属于 JDK 提供的注解,默认注入逻辑为 ** 先按名称( byName)匹配,若存在多个同类型  Bean,则再尝试按类型( byType)筛选 ** 。
266269
267270` @Resource `  有两个比较重要且日常开发常用的属性:` name ` (名称)、` type ` (类型)。
268271
@@ -287,13 +290,15 @@ private SmsService smsServiceImpl1;
287290private  SmsService  smsService;
288291``` 
289292
290- 简单总结一下:
293+ ** 简单总结一下** :
291294
292295-  ` @Autowired `  是 Spring 提供的注解,` @Resource `  是 JDK 提供的注解。
293296-  ` Autowired `  默认的注入方式为` byType ` (根据类型进行匹配),` @Resource ` 默认注入方式为 ` byName ` (根据名称进行匹配)。
294297-  当一个接口存在多个实现类的情况下,` @Autowired `  和` @Resource ` 都需要通过名称才能正确匹配到对应的 Bean。` Autowired `  可以通过 ` @Qualifier `  注解来显式指定名称,` @Resource ` 可以通过 ` name `  属性来显式指定名称。
295298-  ` @Autowired `  支持在构造函数、方法、字段和参数上使用。` @Resource `  主要用于字段和方法上的注入,不支持在构造函数或参数上使用。
296299
300+ 考虑到 ` @Resource `  的语义更清晰(名称优先),并且是 Java 标准,能减少对 Spring 框架的强耦合,我们通常** 更推荐使用 ` @Resource ` ** ,尤其是在需要按名称注入的场景下。而 ` @Autowired `  配合构造器注入,在实现依赖注入的不可变性和强制性方面有优势,也是一种非常好的实践。
301+ 
297302### 注入 Bean 的方式有哪些?  
298303
299304依赖注入 (Dependency Injection, DI) 的常见方式:
0 commit comments