等待静态初始化程序

时间:2016-01-27 10:37:20

标签: 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());
    }
} 

问题是f在加载ServiceImpl之前被调用,它会陷入僵局。

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

1 个答案:

答案 0 :(得分:2)

您的方法过于复杂。您不必担心同步或其中任何一种。

最明显的简化是将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);
  }
}

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