Java 如何将属性值注入枚举?

Java 如何将属性值注入枚举?,java,spring,enums,Java,Spring,Enums,我使用Spring从属性文件解析属性值,通常使用@Value(${my.property}”) 现在我有了一个枚举,它应该有一个应用程序范围的可配置静态编号。例如: public enum PersonType { ADULT, CHILD; private static final int MAX_CHILD = 17; public static PersonType fromAge(int age) { return age <= MAX_C

我使用
Spring
从属性文件解析属性值,通常使用
@Value(${my.property}”)

现在我有了一个枚举,它应该有一个应用程序范围的可配置静态编号。例如:

public enum PersonType {
    ADULT, CHILD;
    private static final int MAX_CHILD = 17;

    public static PersonType fromAge(int age) {
        return age <= MAX_CHILD ? CHILD : ADULT;
    }
}
public enum PersonType{
成人、儿童;
私有静态最终int MAX_CHILD=17;
公共静态PersonType fromAge(int-age){

返回年龄根据可配置的年龄移动逻辑以获得适当的枚举可以是解决方案之一

class PersonTypeFinder
{
    private int maxChildAge; // set this from spring
    ....

   public PersonType getPersonType(int age)
   {
     return age <= maxChildAge ? PersonType.CHILD : PersonType.ADULT;
   }
}

enum PersonType 
{
   ADULT, CHILD;
}
类PersonTypeFinder
{
private int maxChildAge;//从spring设置
....
公共PersonType getPersonType(int年龄)
{

return age这是一个有趣的问题,如何处理与类的所有对象相同且在运行时不会更改的变量,同时允许在执行之间进行配置。因为前两个先决条件要求变量应该是静态的和最终的(例如常量),第三个确实不适合,这意味着没有很好的方法来实现这三个(需要反射,或者必须放弃静态约束或最终约束)

既然现在对事物建模的方式没有很好的解决方案,我认为最明智的做法是后退一步,重新考虑变量的位置:是否有必要将此逻辑保留在枚举本身?更改常量、枚举本身或其他值时有什么不同?在什么情况下,此常量具有要改变它的值吗

在您的示例中,可能是不同的国家对被视为成人的内容有不同的阈值,或者阈值发生了变化,然后可能是一个小型服务来确定
PersonType
a
Person
的正确方式

@Service
public class PersonTypeService {
    @Value("${threshold.for.adulthood}")
    private int thresholdForAdulthood;

    public PersonType determinePersonType(final Person person) {
        if (person.getAge() >= thresholdForAdulthood) {
            return PersonType.ADULT;
        }
        return PersonType.CHILD;
    }  
}

一般来说,我喜欢让enum只回答“什么”,而不回答“如何”和“为什么”到域类和服务。在本例中,枚举需要知道的只是它提供给某人的值,为什么它应该提供某个值,或者它是如何确定的,不属于枚举中。

以前也有人问过类似的问题-。简短的回答是你不能。长的回答是你可以,虽然有一些非常难看的反映,但是不要这样做。你可以编写一个@Component,将你的值注入到某个字段中,并使用@PostConstruct中的反射设置静态最终字段这是一个创建初始化后组件的好主意。我可能会这样做,因为我不希望依赖反射。-我认为更好的方法是移出
PersonType.fromAge
PersonUtils
中作为
fromAge(int-age,int-maxAge)
并使用spEL和属性注入。
这是我的观点,但将实用程序代码放入enum不是一个好的做法;
enum
s被设计为包含值,而不是让代码可以通过许多其他方式重构,只要该字段保持静态,最终反射是您唯一的选择(因为它在类加载时初始化)。将其移动到实用程序类中的静态方法,正如@LucaBassoRicci所建议的,这是更干净的选项