【发布时间】:2019-12-27 09:16:14
【问题描述】:
我一直在 Spring boot 中使用 @Autowired 进行依赖注入。从我读过的所有关于依赖注入的文章中,他们提到当我们(如果)决定将来更改实现类时,依赖注入非常有用。
例如,让我们处理一个Car 类和一个Wheel 接口。 Car 类需要实现Wheel 接口才能工作。所以,我们继续在这个场景中使用依赖注入
// Wheel interface
public interface Wheel{
public int wheelCount();
public void wheelName();
...
}
// Wheel interface implementation
public class MRF impements Wheel{
@Override
public int wheelCount(){
......
}...
}
// Car class
public class Car {
@Autowired
Wheel wheel;
}
现在在上面的场景中,ApplicationContext 会发现有一个 Wheel 接口的实现,从而将它绑定到 Car 类。将来,如果我们将实现更改为 XYZWheel 实现类并删除 MRF 实现,那么同样应该工作。
但是,如果我们决定在我们的应用程序中保留Wheel 接口的两个实现,那么我们需要在自动装配时特别提及我们感兴趣的依赖项。因此,更改将如下 -
// Wheel interface
public interface Wheel{
public int wheelCount();
public void wheelName();
...
}
@Qualifier("MRF")
// Wheel interface implementation
public class MRF impements Wheel{
@Override
public int wheelCount(){
......
}...
}
// Wheel interface implementation
@Qualifier("XYZWheel")
public class XYZWheel impements Wheel{
@Override
public int wheelCount(){
......
}...
}
// Car class
public class Car {
@Autowired
@Qualifier("XYZWheel")
Wheel wheel;
}
所以,现在我必须手动定义我想要自动装配的具体实现。那么,依赖注入在这里有什么帮助呢?我可以很好地使用 new 运算符来实际实例化我需要的实现类,而不是依赖 Spring 为我自动装配它。
所以我的问题是,当我有多个实现类并因此需要手动指定我感兴趣的类型时,自动装配/依赖注入有什么好处?
【问题讨论】:
-
你创造了界限。
Car不关心更改。您可以以某种方式实现它,这样您就不必更改Car中的任何内容(在XYZWheel中使用@Primary)。如果有任何机会,在新的XYZWheel中出现问题,该错误包含在XYZWheel的单元中。一些备注:你应该使用@Inject而不是@Autowired--- 你应该更喜欢构造函数注入而不是字段注入。 -
@Turing85 using
@Primary只是将关注点转移到实现类,不是吗?我们现在不使用限定符,而是在实现类中指定我们选择的 bean。此外,如果XYZWheel中出现问题,自动装配如何解决问题?如果我使用 XYZ bean,无论我使用 Autowired 还是使用new手动实例化它的 bean,我最终都会遇到错误 -
这正是用例。如果您有多个实现,您通常希望在运行时选择实现。如果你可以在编译时选择,你甚至不需要接口。
-
更准确地说:你不想主动选择。在大多数情况下,决定是通过在场(OP 描述的第一个场景)完成的:通过将一个(并且只有一个!)数据库驱动程序放在类路径上来选择数据库驱动程序。如果没有或有多个,我们很可能会看到来自 DI 容器的错误。
标签: java spring spring-boot dependency-injection autowired