处理系统作为依赖

时间:2011-02-09 21:56:28

标签: java dependency-injection

是否有一种方法可以在依赖注入中使用java.lang.System?

目前我正在构建我的课程

public class MyClass
{
    private final Dependency iDependency;

    public MyClass(Dependency pDependency)
    {
        this.iDependency = pDependeny;
    }

    public static MyClass createInstance()
    {
        final Dependency tDependency = Dependency.createInstance();
        final MyClass tInstance = new MyClass(tDependency);
        return tInstance;
    }

    // ... class methods ...
}

并使用:

创建它
MyClass tMyClass = MyClass.createInstance();

对于测试我使用:

@Test
public void testMethod()
{
    // Setup
    Dependency tTestDependency = new TestDependency();
    MyClass tMyClass = new MyClass(tTestDependency);
    // Test
    tMyClass.method();
}

现在我遇到了java.lang.System作为依赖项的问题,因为我想编写一个控制台记录器。我没有问题将System设置为依赖关系的Datatyp,但是当我想将System设置为参数时,Eclipse说不。我收到错误“系统无法解析为变量”。

public class ConsoleLogger
{
    private final System iSystem; // works

    public MyClass(System pSystem) // works
    {
        this.iSystem = pSystem;
    }

    public static ConsoleLogger createInstance()
    {
        final ConsoleLogger tInstance = new ConsoleLogger(System); // Here I get an error: System cannot be resolved to a variable
        return tInstance;
    }

    public void logInfo(String pMessage)
    {
        final String tPrintMsg = this.iSystem.currentTimeMillis() + " INFO - " + pMessage;
        this.iSystem.out.println(tPrintMsg);
    }
}

我可以使用数据类型PrintStream将System.err和System.out设置为依赖项,但仍然不会覆盖System.currentTimeMillies()。

有人知道如何在这种情况下将System作为依赖项处理?

3 个答案:

答案 0 :(得分:3)

  

System类包含几个有用的类字段和方法。 无法实例化。

我认为您必须创建一个接口并使用委托实现。即使这样,它也不会完全相同,因为你不能使用静态方法。

interface MySystem {
    PrintStream getOut();
    InputStream getIn();
    ....
}

class MySystemImpl {
    PrintStream getOut() {
        return System.out;
    }
    ...
}

答案 1 :(得分:1)

你在做什么并没有多大意义。 System类为final并且具有private构造函数,因此您无法对其进行实例化。此外,它的所有方法和字段都是静态的,因此无点实例化它,无点具有该类型的变量。

只是为了帮助您理解,当您通过对实例的引用引用静态方法或字段时,将忽略该引用。因此,这两个版本的logInfo完全相同。

public void iLogInfo(String pMessage)
{
    final String tPrintMsg = this.iSystem.currentTimeMillis() + " INFO - " + pMessage;
    this.iSystem.out.println(tPrintMsg);
}

public void sLogInfo(String pMessage)
{
    final String tPrintMsg = System.currentTimeMillis() + " INFO - " + pMessage;
    System.out.println(tPrintMsg);
}

(这是Java语言允许您编写的代码与其看起来有点不同的情况之一。样式检查器和(IIRC)某些IDE会在您通过静态成员引用静态成员时发出警告实例参考.IMO注意警告是个好主意。)

答案 2 :(得分:0)

System.out,System.in和System.err以及System.currentTimeMillis()都是System上的静态方法。我会弄清楚和错误的依赖关系,然后有一个DateUtil bean,您可以使用方法currentTimeMillis连接。您可以使用SystemWrapper bean执行此操作,但out和err似乎与日期操作非常分开。