Java IoC和依赖注入
以下代码有什么问题Java IoC和依赖注入,java,jakarta-ee,dependency-injection,inversion-of-control,Java,Jakarta Ee,Dependency Injection,Inversion Of Control,以下代码有什么问题 public class DeDoper { public boolean wackapediaOkToday() { DnsResolver resolver = ResolverFactory.getInstance().makeResolver(); return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9"
public class DeDoper {
public boolean wackapediaOkToday() {
DnsResolver resolver = ResolverFactory.getInstance().makeResolver();
return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9");
}
}
为什么首选此版本
public class DeDoper {
@InjectService
private DnsResolver resolver;
public boolean wackapediaOkToday() {
return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9");
}
}
我可以很容易地模拟ResolverFactory.makeResolver(),这与设置resolver是最新的示例相同
这是ProQuest.biz中所说的:
这个(第一个)版本的WackapediaOkToday,非常宽松地说,“注入”了一个DnsResolver(尽管不可否认,这不像是一次注射,更像是向服务员要支票)。但它确实解决了测试问题,以及“海龟一路向下”的问题
被锁在工厂里
但是在这个(第一个版本)的方法中,我们实际上是“链接”到工厂类的。(更糟糕的是,如果工厂创建的对象依次具有依赖性,我们可能必须在工厂中引入新的工厂。)我们没有完全“反转”我们的控件,我们仍然从类内部调用(控制)工厂
我们需要的是一种完全摆脱类中的控制的方法,并让他们告诉他们得到了什么(对于他们的依赖性)
假设您有一个可以有多个实现的服务,比如“FileLocator”。这有一个FilesystemFileLocator,它以文件根目录的路径作为参数,还有一个S3FileLocator,它以S3凭据作为参数。前者需要您编写一个服务定位器,以确定所需的版本,然后返回该版本。这些代码,反过来,必须去获取你的数据,构建适当类型的文件定位器,等等。你正在做IOC容器应该为你做的事情。最重要的是,您已经在特定的创建方法上注入了依赖项 在第二个版本中,您已经(通过注释或XML)定义了所需的文件定位器的类型。IOC容器为您实例化并管理它。您需要维护的代码更少。如果您想引入第三种类型的FileLocator,那么工作也会少一些。或者,您可以重构代码,使文件定位器成为单例,或者,如果它们是单例,那么它们现在就是新定位器的工厂,或者您可能希望将定位器实例合并到一起。在所有这些情况下,如果您使用IOC容器,破损会更少