Web服务处理程序中的静态块

时间:2013-06-04 06:56:21

标签: java multithreading web-services jax-ws

我有一个带有多个处理程序的jax-ws Web服务。我有一个特定的对象,启动性能明显昂贵。我需要这个对象来处理每个请求来到Web服务。

将此对象放入静态块是否是一种解决方案?由于静态块是在类加载时创建的,因此可以提高性能。但它仍然能实现我的需要。我需要将相同的对象保存在内存中并重用于所有请求。但正如我所知,在Web服务中,每个请求都分配给静态块中的线程对象,不会被线程共享。它是?

期待这里的一些解释。

谢谢

1 个答案:

答案 0 :(得分:2)

静态块是一段代码,在类加载器初始化类时运行一次。您可以使用它来设置复杂对象,然后在静态变量中保留对它的引用,如下所示:

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这样的依赖注入框架来设置singletons

非常容易
  

当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;
    }
}