Java 使静态变量可注入

Java 使静态变量可注入,java,dependency-injection,Java,Dependency Injection,我正在构建一个http API客户端,它需要调用特定的端点,如下所示: public class MyApiClient { private static final String ENDPOINT ="http://myapi...."; } 在这里端点不会改变,所以它是常量。但是,我希望能够覆盖此测试,以便可以针对模拟http服务器进行测试 最好的方法是什么?是否只是将其作为实例变量并为其提供一个起始值: private String endpoint = ="http://my

我正在构建一个http API客户端,它需要调用特定的端点,如下所示:

public class MyApiClient {
    private static final String ENDPOINT ="http://myapi....";

}
在这里端点不会改变,所以它是常量。但是,我希望能够覆盖此测试,以便可以针对模拟http服务器进行测试

最好的方法是什么?是否只是将其作为实例变量并为其提供一个起始值:

private String endpoint = ="http://myapi....";

public void setEndpoint(String endpoint){
   ...
}

当然,有很多解决方案,其中一种方法是使用具有默认值的系统属性:

private static final String DEFAULT_ENDPOINT = "http://myapi....";
private static final String ENDPOINT = 
        System.getProperty("my.endpoint", DEFAULT_ENDPOINT);
通过这种方式,您可以获得解决问题的可配置方式。如果在初始化静态常量时需要更大的灵活性,还可以使用静态初始值设定项:

系统属性在命令行上作为
-D
参数传递,例如:

java -Dmy.endpoint=http://...

但在我看来,一个更好的方法是向使用它的类实际注入值:

public class ClassThatIsUsingTheConfig {
    private final String endpoint;
    public ClassThatIsUsingTheConfig(final String endpoint) {
        this.endpoint = endpoint;
    }

    public void someMethod() {
        // use endpoint
    }
}
然后,选择要在调用方类中使用的端点。从测试用例来看,这将非常容易模拟

public class MyTest {
    @Test
    public void testMethod() {
        ClassThatIsUsingTheConfig var = new ClassThatIsUsingTheConfig(TEST_ENDPOINT);
        var.someMethod();
    }
}

public class MyProdClass {
    public void prodMethod() {
        ClassThatIsUsingTheConfig var = new ClassThatIsUsingTheConfig(PROD_ENDPOINT);
        var.someMethod();
    }
}
你可以阅读更多关于


另一方面,如果您正在使用某种框架来管理依赖项,例如,或通常能够以各种方式(例如,基于当前运行的环境)注入属性和常量。例如,使用Spring Framework时,可以在属性文件中声明所有常量,并使用注释插入属性:

@Autowired
public ClassWhoIsUsingTheConfig(@Value("my.endoint") final String endpoint) {
    this.endpoint = endpoint;
}
prod的属性文件可以如下所示:

my.endpoint=http://prodserver...

测试的属性文件如下所示:

my.endpoint=http://testserver...

使用依赖项注入引擎的方法允许以非常灵活的方式处理外部常量、路径、资源等,并简化了测试代码的过程。

如果
字符串端点必须是静态的,则从
静态方法的结果中分配其值,其中,此方法从配置文件或其他数据源读取正确的值。这是使用WSDL和JAX-WS时的问题之一。
my.endpoint=http://testserver...