如何在Java枚举类中获取properties配置文件中的属性值
根本原因
枚举类是JDK层面的实现,在类加载阶段就会完成所有枚举实例的初始化,这个时机远早于Spring容器的初始化、Bean依赖注入流程,因此Spring提供的@Autowired、@Value等注入注解无法对枚举实例生效,直接在枚举初始化阶段赋值会触发未初始化的编译错误。
可行解决方案
方案1:静态Spring上下文工具类获取
实现ApplicationContextAware编写Spring上下文工具类,把容器上下文暴露为静态资源,在枚举需要使用配置时调用工具类获取对应属性。
- 编写Spring上下文工具类
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext CONTEXT; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { CONTEXT = applicationContext; } // 直接获取配置属性 public static String getProperty(String key) { return CONTEXT.getBean(Environment.class).getProperty(key); } // 可扩展获取任意Spring Bean public static <T> T getBean(Class<T> clazz) { return CONTEXT.getBean(clazz); } }
- 枚举类内惰性获取配置
public enum Test { ABC{..}, DEH{..}; // 不在初始化阶段赋值,改为调用时动态获取 public String getConstantTwo() { return SpringContextUtil.getProperty("MY_CONSTANT"); } }
方案2:容器初始化完成后主动为枚举赋值
在Spring配置类内通过@PostConstruct在容器初始化完成、配置注入完毕后,主动给枚举的成员变量赋值。
- 调整枚举类结构,提供属性set方法
public enum Test { ABC{..}, DEH{..}; private String constantTwo; public String getConstantTwo() { return constantTwo; } public void setConstantTwo(String constantTwo) { this.constantTwo = constantTwo; } }
- 编写配置类初始化枚举属性
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; @Configuration public class EnumPropertyConfig { @Value("${MY_CONSTANT}") private String myConstant; @PostConstruct public void injectEnumConstant() { for (Test testEnum : Test.values()) { testEnum.setConstantTwo(myConstant); } } }
该方案优势为配置值仅赋值一次,后续调用无需重复读取上下文,性能更高。
注意事项
- 两种方案都要求调用枚举配置属性的时机晚于Spring容器初始化完成,常规业务层、控制层调用均符合要求,不要在静态代码块、应用启动前置逻辑中提前调用,避免空指针。
- 如果需要脱离Spring环境也能读取枚举配置,可以在枚举的静态代码块中通过JDK原生
Properties.load()方法直接读取配置文件,无需依赖Spring容器。
内容的提问来源于stack exchange,提问作者Sardothien
相关产品推荐
相关产品推荐

