在 Java 枚举中使用 Spring 注入

Using Spring injection inside a Java enum

我遇到的情况是,我的申请可能恰好是几个 "modes" 中的一个。由于这些是离散值,我想使用枚举类型对它们进行建模。

对于每个状态,我的应用程序需要执行略有不同的功能,我想使用插件模式对其进行建模。我已经定义了一个接口并提供了一些实现。

我现在想要枚举 return 适合其状态的插件。我喜欢做以下事情:

public enum Mode {
  ONE {
    @Override
    public MyType get() { return factory.getFirst(); }
  },
  TWO {
    @Override
    public MyType get() { return factory.getSecond(); }
  };

  @Autowired private MyTypeFactory factory;

  public abstract MyType get();

  // Other methods removed for clarity
}

然而,这是行不通的。这是因为我使用 spring 注入将插件工厂添加到枚举中(枚举常量是静态的,而 spring 注入的变量是实例变量,所以我会得到一个编译错误)

我无法直接从枚举创建 MyType 实例,因为它们需要依赖注入

我该如何解决这个问题?

这可能不是最好的解决方案(我希望看到更好的建议),但这是我最终所做的:

修改工厂使其显示为:

public class MyTypeFactory {
  private static MyTypeFactory me;

  @PostConstruct
  public void initialise() {
    if (me == null) {
        me = this;
    }
  }

  public static MyTypeFactory getInstance() {
    return me;
  }

  // The same code as before - getFirst(), getSecond() etc
}

所以,一个(单例)spring 托管 bean 看起来有点像旧的 GOF 单例!重要的区别在于有一个可公开访问的默认(无参数)构造函数

然后我可以将枚举修改为:

public enum Mode {
  ONE {
    @Override
    public MyType get() { Factory.getInstance().getFirst(); }
  },
  TWO {
    @Override
    public MyType get() { Factory.getInstance().getSecond(); }
  };

  public abstract MyType get();

  // Other methods removed for clarity
}

调用 get() 时,枚举可以通过静态 getInstance 方法访问工厂