为什么我们不应该使用查找而不是依赖注入?
Why should we not use look up instead of dependency injection?
是否有任何充分的理由不在应用程序上下文中查找对象而不是“假设”注入了依赖项?
例如:
public Dependency getDependency(){
if (dependency == null){
dependency = (Dependency) applicationContext.getBean("dependency");
}
return dependency;
}
有争议的论点
污染对象 Spring 特定对象
有些人可能会抱怨使用应用程序上下文会将实现与 Spring 内容绑定在一起。但是,创建对 applicationContext 的间接访问可以轻松解决。好的...让我举例说明:
public Dependency getDependency(){
if (dependency == null){
dependency = (Dependency) serviceLocator.getBean("dependency");
}
return dependency;
}
难以更改实现
首先,它(依赖对象)可以在应用程序上下文中轻松更改。但是,使用通常的修改器可以直接插入模拟更容易:
public void setDependency(Dependency dep){
this.dependency = dep;
}
历史问题
很久以前,Java 世界上的每个人都在使用服务定位器(通过称为 JNDI 的技术在目录服务中)来拥有可互换的对象基础结构。我们可以在目录服务中绑定三种对象:可序列化数据、引用或 Dircontext。它还允许您在分布式环境中查找对象。
然后,我们进行了 Spring 革命,现在大多数情况下都使用 DI(依赖注入)。
但是,Spring 并未禁止服务定位器模式。例如,使用 ApplicationContext 允许我们以服务定位器的方式查找 bean。我们可以认为 Spring 框架提供了一个带有集中配置的大型对象工厂、依赖注入工具以及一个可以轻松处理的服务目录。最后一段差点忘记了。
相关问题
Why is Spring's ApplicationContext.getBean considered bad?
我不考虑,因为这些答案虽然有启发性,但并没有启发上面提出的观点。
我个人对此的看法。
通过注释易于使用 DI 与必须通过 applicationContext 获取 bean 相比。
但归根结底,我认为主要区别在于依赖项的位置。
服务位置需要客户端代码请求相关的特定依赖项,而使用依赖项注入,容器会创建所有对象并将这些依赖项作为构造函数参数注入。
坦率地说,最终两者都是可行的,但考虑一下:据我所知,JNDI 查找在性能方面非常昂贵,因此最终建议您缓存它们。
注入的服务组件比使用服务定位器的服务组件更简单,而且更简单通常是更好的工程。使用依赖注入的 Bean 只是常规的旧 Java 对象,(有时)碰巧在构造函数上有 @Inject
注释(Spring JavaConfig bean 甚至可能不需要任何那)。该 bean 无需手动与查找代码交互,如果您需要更改传递给它的依赖项(例如,以便您可以注入模拟),管理其自身依赖项的 bean 将需要很多更多基础设施即将建成。
是否有任何充分的理由不在应用程序上下文中查找对象而不是“假设”注入了依赖项? 例如:
public Dependency getDependency(){
if (dependency == null){
dependency = (Dependency) applicationContext.getBean("dependency");
}
return dependency;
}
有争议的论点
污染对象 Spring 特定对象
有些人可能会抱怨使用应用程序上下文会将实现与 Spring 内容绑定在一起。但是,创建对 applicationContext 的间接访问可以轻松解决。好的...让我举例说明:
public Dependency getDependency(){
if (dependency == null){
dependency = (Dependency) serviceLocator.getBean("dependency");
}
return dependency;
}
难以更改实现
首先,它(依赖对象)可以在应用程序上下文中轻松更改。但是,使用通常的修改器可以直接插入模拟更容易:
public void setDependency(Dependency dep){
this.dependency = dep;
}
历史问题
很久以前,Java 世界上的每个人都在使用服务定位器(通过称为 JNDI 的技术在目录服务中)来拥有可互换的对象基础结构。我们可以在目录服务中绑定三种对象:可序列化数据、引用或 Dircontext。它还允许您在分布式环境中查找对象。
然后,我们进行了 Spring 革命,现在大多数情况下都使用 DI(依赖注入)。
但是,Spring 并未禁止服务定位器模式。例如,使用 ApplicationContext 允许我们以服务定位器的方式查找 bean。我们可以认为 Spring 框架提供了一个带有集中配置的大型对象工厂、依赖注入工具以及一个可以轻松处理的服务目录。最后一段差点忘记了。
相关问题
Why is Spring's ApplicationContext.getBean considered bad?
我不考虑,因为这些答案虽然有启发性,但并没有启发上面提出的观点。
我个人对此的看法。 通过注释易于使用 DI 与必须通过 applicationContext 获取 bean 相比。 但归根结底,我认为主要区别在于依赖项的位置。 服务位置需要客户端代码请求相关的特定依赖项,而使用依赖项注入,容器会创建所有对象并将这些依赖项作为构造函数参数注入。 坦率地说,最终两者都是可行的,但考虑一下:据我所知,JNDI 查找在性能方面非常昂贵,因此最终建议您缓存它们。
注入的服务组件比使用服务定位器的服务组件更简单,而且更简单通常是更好的工程。使用依赖注入的 Bean 只是常规的旧 Java 对象,(有时)碰巧在构造函数上有 @Inject
注释(Spring JavaConfig bean 甚至可能不需要任何那)。该 bean 无需手动与查找代码交互,如果您需要更改传递给它的依赖项(例如,以便您可以注入模拟),管理其自身依赖项的 bean 将需要很多更多基础设施即将建成。