如果使用 @Resource 进行注入,它会先按照名称查找,即先查找名称为 "fooService" 的 Bean,由于没有找到,所以会按照类型查找,最终找到的是 FooServiceImpl1 实例,并注入到 fooService 属性中,请详细解释这里面的按照类型查找为什么不会报错
时间: 2024-02-29 18:53:39 浏览: 45
在使用 `@Resource` 进行注入时,如果按照名称查找没有找到对应的 Bean,则会按照类型进行查找。如果按照类型查找到了多个符合条件的 Bean,则会抛出异常;如果只找到了一个符合条件的 Bean,则会直接注入。
在你提到的例子中,首先按照名称查找 Bean,但是当前容器中没有名称为 "fooService" 的 Bean,所以会按照类型进行查找。在容器中找到了两个实现 `FooService` 接口的 Bean,分别是 `FooServiceImpl1` 和 `FooServiceImpl2`,但是由于没有指定名称,所以只会按照类型进行匹配。
因为 `fooService` 属性的类型是 `FooService` 接口,而 `FooServiceImpl1` 实现了 `FooService` 接口,所以它是符合条件的 Bean。另外一个实现 `FooService` 接口的 Bean `FooServiceImpl2` 因为类型不匹配,所以不会被选中。
因此,在使用 `@Resource` 进行注入时,如果按照名称查找没有找到对应的 Bean,会按照类型进行查找。如果只找到了一个符合条件的 Bean,则会直接注入,不会报错。只有在找到了多个符合条件的 Bean 时,才会抛出异常。
相关问题
如果使用 @Autowired 进行注入,它只会按照类型查找,由于存在多个实现 FooService 接口的 Bean,所以会抛出 NoUniqueBeanDefinitionException 异常,提示找到了多个符合条件的 Bean,无法确定注入哪一个。为什么@resource按照类型查找不出错,但是这里的按照类型查找就会出错
虽然 `@Resource` 和 `@Autowired` 都可以按照类型进行查找,但是它们的具体实现方式不同,导致它们的用法和限制也有所不同。
具体来说,`@Resource` 先按照名称进行查找,如果找到了名称匹配的 Bean,则直接注入;如果没有找到,则按照类型进行查找。因此,如果在容器中有同类型的多个 Bean,使用 `@Resource` 注入时需要指定名称,否则会抛出 `NoUniqueBeanDefinitionException` 异常。
而 `@Autowired` 则直接按照类型进行查找,如果找到了多个类型匹配的 Bean,则会抛出 `NoUniqueBeanDefinitionException` 异常,需要手动指定需要注入的 Bean。此外,`@Autowired` 还支持根据名称进行查找,可以使用 `@Qualifier` 注解指定需要注入的 Bean 的名称。
因此,在实际使用中,如果存在多个符合条件的 Bean,使用 `@Autowired` 进行注入时会抛出 `NoUniqueBeanDefinitionException` 异常,需要手动指定需要注入的 Bean。而使用 `@Resource` 进行注入时,则会按照名称进行查找,如果没有找到对应名称的 Bean,则会按照类型进行查找,如果找到了多个符合条件的 Bean,则会抛出异常。
所以,可能是因为 `@Resource` 先按照名称查找,如果没有找到对应名称的 Bean,则会按照类型进行查找,并且默认只注入找到的第一个 Bean,所以不会报错。而 `@Autowired` 直接按照类型查找,如果找到多个 Bean,则会抛出异常。
如果有多个实现 FooService 接口的 Bean,为什么使用@Resource注解不报错使用@Autoweired报错,请举例说明
@Resource 和 @Autowired 注解的主要区别在于它们的查找顺序不同。@Resource 会先按照名称查找,如果找不到再按照类型查找;而 @Autowired 只会按照类型查找。
举个例子,假设有如下代码:
```
public interface FooService {}
@Service("fooServiceImpl1")
public class FooServiceImpl1 implements FooService {}
@Service("fooServiceImpl2")
public class FooServiceImpl2 implements FooService {}
@Service
public class BarService {
@Resource
private FooService fooService;
@Autowired
private FooService fooService2;
}
```
在这个例子中,有两个实现 FooService 接口的 Bean,分别是 FooServiceImpl1 和 FooServiceImpl2,它们都被标记为@Service,并且分别使用了不同的名称。
在 BarService 中,有两个属性需要注入 FooService 实例,分别是 fooService 和 fooService2,分别使用了 @Resource 和 @Autowired 进行注入。
如果使用 @Resource 进行注入,它会先按照名称查找,即先查找名称为 "fooService" 的 Bean,由于没有找到,所以会按照类型查找,最终找到的是 FooServiceImpl1 实例,并注入到 fooService 属性中。
如果使用 @Autowired 进行注入,它只会按照类型查找,由于存在多个实现 FooService 接口的 Bean,所以会抛出 NoUniqueBeanDefinitionException 异常,提示找到了多个符合条件的 Bean,无法确定注入哪一个。
阅读全文