Enum 使用 Spring 组件类(Bean)
前言
忽略合理性,如果遇到需要在 枚举类 中使用 Spring 组件(bean
)的需求,直接注入肯定是行不通的的,可以借由 内部类 暴露需要的 组件
示例
组件类 MyBeanA
@Component
public class MyBeanA {
private String value = "dd";
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
枚举类 MyEnum
public enum MyEnum {
E1("v1");
String value;
MyEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
假设我们想让 枚举 值取自 MyBeanA,直接注入 MyBeanA 明显不可行,我们可以将 MyBeanA 交由一个同样由 Spring 管理的类管理,出于方便和专用,且要在 枚举 类使用,声明为 静态内部类
内部类 MyBeanAContainer
@Component
static class MyBeanAContainer {
@Autowired
MyBeanA myBeanA;
private static MyBeanA _myBeanA;
@PostConstruct
public void init() {
_myBeanA = myBeanA;
}
static MyBeanA getMyBeanA() {
return _myBeanA;
}
}
静态属性无法直接注入,我们借由 @PostConstruct
初始化回调为它赋值,该回调方法在所有 bean
注册完成后,因此没有问题
该方法也是解决 静态属性注入 最常用的方法
测试
现在,我们添加一个枚举 E2,其属性值从 组件 读取
E1("v1"), E2("") {
@Override
public String getValue() {
return MyBeanAContainer.getMyBeanA().getValue();
}
};
直接在 主类 测试
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(MyEnum.E1.getValue());
System.out.println(MyEnum.E2.getValue());
}
}
}
结果:
v1
dd
总结
借由 静态内部类,我们解决了 Enum 中注入 Spring 组件类的问题