我有一个带有多个处理程序的 jax-ws Web 服务。我有一个特定的对象,它在性能方面的启动成本很高。我需要这个对象来处理每个请求到 Web 服务。
将此对象放入静态块是否是一种解决方案?由于静态块是在类加载时创建的,因此它会提高性能。但它仍然能达到我所需要的。我需要将相同的对象保存在内存中并重复用于所有请求。但正如我所知,在 Web 服务中,每个请求都分配给静态块中的线程对象,不会被线程共享。这是?
期待这里的一些解释。
谢谢
我有一个带有多个处理程序的 jax-ws Web 服务。我有一个特定的对象,它在性能方面的启动成本很高。我需要这个对象来处理每个请求到 Web 服务。
将此对象放入静态块是否是一种解决方案?由于静态块是在类加载时创建的,因此它会提高性能。但它仍然能达到我所需要的。我需要将相同的对象保存在内存中并重复用于所有请求。但正如我所知,在 Web 服务中,每个请求都分配给静态块中的线程对象,不会被线程共享。这是?
期待这里的一些解释。
谢谢
静态块是在类加载器初始化类时运行一次的一段代码。您可以使用它来设置您的复杂对象,然后在静态变量中保留对它的引用,如下所示:
public class MyClass {
private static final LanguageLookup languageLookup;
static {
languageLookup = new LanguageLookup ();
languageLookup.loadData();
}
public Response handleRequest(Request request) {
String language = languageLookup.lookup(request.getCountryCode());
response.setLanguage(language);
return response;
}
}
如果您在 servlet 或 web 服务等多线程环境中执行此操作,您需要确保 LanguageLookup 的状态在其初始化后不会改变。如果它使用自己的依赖项进行初始化以外的操作,这些也必须是无状态的。
我认为这样做通常不是一个好主意,因为您将类硬连接到 LanguageLookup,使其紧密耦合且更难进行单元测试。
使用像 Spring 这样的依赖注入框架来设置单例非常容易:
当一个 bean 是单例时,只有一个 bean 的共享实例将被管理,并且所有对 id 或 id 与该 bean 定义匹配的 bean 的请求将导致返回一个特定的 bean 实例。
在应用程序上下文中,您将拥有如下内容:
<bean name="languageLookup" class="com.acme.foo.LanguageLookup" singleton="true" init-method="loadData"/>
在您的代码中:
public class MyClass {
private LanguageLookup languageLookup;
public Response handleRequest(Request request) {
String language = languageLookup.lookup(request.getCountryCode());
response.setLanguage(language);
return response;
}
// called by Spring
public void setLanguageLookup(LanguageLookup languageLookup) {
this.languageLookup = languageLookup;
}
}