java - 等待静态初始化程序

标签 java dependency-injection

我希望类中有一个静态字段,以便在加载另一个类时自动初始化。

类似这样的事情:

class ServiceBase {
    static Object lock = new Object();
    static ServiceBase service;
    static void setService(ServiceBase service) {
        synchronized (lock) {
            ServiceBase.service = service;
            lock.notifyAll();
        }
    }
    void f() throws Exception {
        synchronized (lock) {
            while (service == null){
                lock.wait();            
            }
       }
       //use service
   }
}

class ServiceImpl extends ServiceBase {
    static {
        ServiceBase.setService(ne ServiceImpl());
    }
} 

问题是在加载ServiceImpl之前调用f,它会陷入死锁。

初始化服务实例的最佳方法是什么? (我无法使用Spring或其他大型框架)

最佳答案

您的方法过于复杂。您不需要担心同步或任何其他问题。

最明显的简化是将 Service 实例作为构造函数参数传递给 ServiceBase:

class ServiceBase {
  private final Service service;

  ServiceBase(Service service) {
    this.service = checkNotNull(service);
  }

  void f() {
    // service is guaranteed to be present.
  }
}

这样,在非空服务可用之前,您永远无法实际调用 f()

如果您希望每次都使用相同的 ServiceImpl 实例,请创建一个 ServiceBaseProvider 类,用于获取 ServiceBase 的实例,而不是直接构造它们:

class ServiceBaseProvider {
  private static ServiceImpl INSTANCE = new ServiceImpl();

  static ServiceBase getInstance() {
    return new ServiceBase(INSTANCE);
  }
}

或者,当然,在需要的地方注入(inject)相同的 ServiceBase 实例,这使得(例如)在测试期间注入(inject)模拟实例变得更加容易。

关于java - 等待静态初始化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35034981/

相关文章:

Java ArrayList 的 ?扩展接口(interface)

java - componentListener 被禁用

java - 将 Struts 1 迁移到 Struts 2

java - 如何设置可选择的JRadioButton的数量

java - 如何使用 POI 删除表格后的第一个字符

dependency-injection - 在 Jersey 过滤器中注入(inject) EJB

c# - ASP.NET 核心 DI : Resolve same instance if scoped service is registered both as service type and implementation type

java - Guice:使用注入(inject)器?

java - 找不到依赖项 : expected at least 1 bean 的 [HrEmployeesReportOutput] 类型的合格 bean

java - Axon 3 未找到处理程序