为什么我们不应该使用查找而不是依赖注入?

时间:2015-03-13 11:09:30

标签: java spring dependency-injection

对于stackoverflow主持人:只需关闭此问题。我已经得到了答案。

有没有充分的理由不在应用程序上下文中查找对象而不是“假设”注入依赖项? 例如:

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;
}

难以改变实施

首先,它(依赖对象)可以在应用程序上下文中轻松更改。但是,使用通常的mutator直接插入模拟更容易:

public void setDependency(Dependency dep){
     this.dependency = dep;
}

历史问题

很久以前,Java世界中的每个人都使用Service Locator(在一个名为JNDI的技术的目录服务中)拥有一个可互换的对象基础结构。我们可以在目录服务中绑定三种对象:可序列化数据,引用或Dircontext。它还允许您在分布式环境中查找对象。

然后,我们进行了Spring革命,现在大多数情况都使用了DI(依赖注入)。

但是,Spring并未禁止服务定位器模式。例如,使用ApplicationContext允许我们以服务定位器的方式查找bean。我们可以认为Spring框架提供了一个具有集中配置的对象的大工厂,依赖注入工具以及可以轻松处理的服务目录。最后一部分几乎被遗忘了。

相关问题

Why is Spring's ApplicationContext.getBean considered bad?

我没有考虑到这一点,因为这些答案虽然有所启发,但并没有启发上述要点。

2 个答案:

答案 0 :(得分:1)

我个人对此的看法。 通过注释易于使用DI而不必通过applicationContext获取bean。 但在一天结束时,我认为主要区别在于依赖关系的定位。 服务位置需要对相关特定依赖项的客户机代码请求,而使用依赖项注入时,容器会创建所有对象并将这些依赖项作为构造函数参数注入。 坦率地说,在一天结束时两者都是可行的,但请考虑一下:据我所知,JNDI查找在性能方面相当昂贵,因此最终建议您缓存它们。

答案 1 :(得分:0)

注入的服务组件比使用服务定位器的组件更简单,更简单的通常是更好的工程。使用依赖注入的Bean只是常规的旧Java对象(有时)恰好在构造函数上注释@Inject(Spring JavaConfig bean甚至可能不需要任何这些)。 bean不需要手动与查找代码连接,如果你需要改变你传递给它的依赖项(比如说,你可以注入一个模拟),那么管理自己的依赖项的bean需要很多建设更多基础设施。