最近寫了前臺一個管理模塊,後來也是我來寫,採用四層架構,在定義接口時,基本是一個接口對應一個實現類,使用@Autowired註解,但我想如果有多個實現類,如何註解,來梳理一下
舉例說明:
1、接口:IAnimal
public Interface IAnimal{
......
}
2、Impl實現:DogImpl ,實現了IAnimal接口。
@Service("dogImpl")
public classDaoImpl impliments Animal{
...
}
3、Controller:AnimalController
public class AnimalController{
@Autowired
private IAnimal dogImpl;
......
}
假如有一個“動物”的接口 IAnimal, DogImpl類實現了接口 IAnimal, 且該接口只有 DogImpl這一個實現類,那麼在引用實現類的時候,我們使用的是實現類的接口(像上面程序展示的那樣)。Spring會按 byType的方式尋找接口的實現類,將其注入。
假如有另一個實現類 CatImpl 也實現了接口 IAnimal, 這時候再按上面的方式去引用, 在同時存在兩個實現類的情況下,會出現什麼情況呢?
答:會報錯。 這是由於 @Autowired 的特性決定的: @Autowired 的注入方式是 byType 注入, 當要注入的類型在容器中存在多個時,Spring是不知道要引入哪個實現類的,所以會報錯。
那麼在同一類型擁有多個實現類的時候,如何注入呢?
答:這種場景下,只能通過 byName 注入的方式。可以使用 @Resource 或 @Qualifier 註解。
@Resource 默認是按照 byName 的方式注入的, 如果通過 byName 的方式匹配不到,再按 byType 的方式去匹配。所以上面的引用可以替換爲:
public class AnimalController{
@Resource(name="dogImpl")
private IAnimal dogImpl;
......
}
@Qualifier 註解也是 byName的方式,但是與@Resource 有區別,@Qualifier 使用的是 類名。
public class AnimalCOntroller{
@Qualifier("DaoInpl")
private IAnimal dogImpl;
...
}
總結:
1、@Autowired 是通過 byType 的方式去注入的, 使用該註解,要求接口只能有一個實現類。
2、@Resource 可以通過 byName 和 byType的方式注入, 默認先按 byName的方式進行匹配,如果匹配不到,再按 byType的方式進行匹配。
3、@Qualifier 註解可以按名稱注入, 但是注意是 類名。