通过依赖注入设置 Java 枚举值
Setting Java Enums values through dependency injection
我用 public 嵌套枚举 class 和一些 setter 创建了一个 class。嵌套枚举 class 使用变量,其值来自通过依赖注入设置到外部 class 的属性文件。我希望使用外部 class 的组件不知道枚举的值并单独循环遍历每个值。枚举将始终在外部 class 之后实例化,因此无需担心变量中的空值。有人告诉我这不是应该使用枚举的方式。建议是写一个 class 模仿枚举 class 而不是仅仅使用枚举。这似乎非常教条,我很好奇人们的想法是什么以及可能的替代方案。我写了类似的东西:
public class myOuterClass {
private static string1;
private static string2;
private static string3;
public enum NestedEnum {
MY_ENUM1("enum1: "+string1),
MY_ENUM2("enum2: "+string2),
MY_ENUM3("enum3: "+string3);
private String enumValue = "";
NestedEnum(String enumValue) {
this.enumValue = enumValue;
}
public String getEnumValue() { return enumValue; }
}
public String printEnum(NestedEnum enum) {
System.out.println(enum.getEnumValue());
return enum.getEnumValue();
}
public void setString1(String string1) {
this.string1 = string1;
}
public void setString2(String string2) {
this.string2 = string2;
}
public void setString3(String string3) {
this.string3 = string3;
}
}
你的方法的问题在于你的枚举实际上并不是依赖注入的;相反,它们拥有自己的实例化逻辑(就像枚举一样),并且它们以一种脆弱且无法执行的方式简单地依赖于在枚举 class 被 class 加载之前完成的依赖注入-装载机。 (请注意,由于枚举是 public,您并不能真正控制这种情况何时发生;您的 DI 框架也不能。)
解决此问题的一种方法是让枚举的构造函数调用您的 DI 框架。 (例如,如果您正在使用 Guice 并且有一个 Injector
的单例实例,您的枚举的构造函数可以向它请求适当的实例,从而保证顺序。)这并不理想——它污染了您的 class 引用您的 DI 设置的代码——但它比您拥有的要好。
当然,另一种方法是不使用 enum
开始:让您的 DI 框架完成它的工作并为您管理您的实例。但是听起来您已经拒绝了这种方法;我要和谁争论?
编辑添加: 您的方法的另一个潜在问题是 "reset" 您的枚举的唯一方法是停止并重新启动 JVM。如果您有多个版本的属性文件(例如,不同的语言版本),那么您的测试框架可能无法测试它们是否都正常工作。 (我上面的第一个建议没有解决这个问题。)
我用 public 嵌套枚举 class 和一些 setter 创建了一个 class。嵌套枚举 class 使用变量,其值来自通过依赖注入设置到外部 class 的属性文件。我希望使用外部 class 的组件不知道枚举的值并单独循环遍历每个值。枚举将始终在外部 class 之后实例化,因此无需担心变量中的空值。有人告诉我这不是应该使用枚举的方式。建议是写一个 class 模仿枚举 class 而不是仅仅使用枚举。这似乎非常教条,我很好奇人们的想法是什么以及可能的替代方案。我写了类似的东西:
public class myOuterClass {
private static string1;
private static string2;
private static string3;
public enum NestedEnum {
MY_ENUM1("enum1: "+string1),
MY_ENUM2("enum2: "+string2),
MY_ENUM3("enum3: "+string3);
private String enumValue = "";
NestedEnum(String enumValue) {
this.enumValue = enumValue;
}
public String getEnumValue() { return enumValue; }
}
public String printEnum(NestedEnum enum) {
System.out.println(enum.getEnumValue());
return enum.getEnumValue();
}
public void setString1(String string1) {
this.string1 = string1;
}
public void setString2(String string2) {
this.string2 = string2;
}
public void setString3(String string3) {
this.string3 = string3;
}
}
你的方法的问题在于你的枚举实际上并不是依赖注入的;相反,它们拥有自己的实例化逻辑(就像枚举一样),并且它们以一种脆弱且无法执行的方式简单地依赖于在枚举 class 被 class 加载之前完成的依赖注入-装载机。 (请注意,由于枚举是 public,您并不能真正控制这种情况何时发生;您的 DI 框架也不能。)
解决此问题的一种方法是让枚举的构造函数调用您的 DI 框架。 (例如,如果您正在使用 Guice 并且有一个 Injector
的单例实例,您的枚举的构造函数可以向它请求适当的实例,从而保证顺序。)这并不理想——它污染了您的 class 引用您的 DI 设置的代码——但它比您拥有的要好。
当然,另一种方法是不使用 enum
开始:让您的 DI 框架完成它的工作并为您管理您的实例。但是听起来您已经拒绝了这种方法;我要和谁争论?
编辑添加: 您的方法的另一个潜在问题是 "reset" 您的枚举的唯一方法是停止并重新启动 JVM。如果您有多个版本的属性文件(例如,不同的语言版本),那么您的测试框架可能无法测试它们是否都正常工作。 (我上面的第一个建议没有解决这个问题。)