【问题标题】:@PostConstruct used with Jersey 1.17, Weblogic@PostConstruct 与 Jersey 1.17、Weblogic 一起使用
【发布时间】:2014-12-05 14:03:11
【问题描述】:

我使用 Jersey 将一些统计数据公开为 REST 服务。 我正在使用 Weblogic

但是每次我执行请求以获取统计信息时 System.out.println("在构造后");被调用。

即使我在路径 @Stateless 旁边注释也会发生这种情况。

这就像 StorageService 在每个请求(req 范围)上实例化

有没有办法只调用一次初始化并避免在每个请求上创建 StorageService ?

@Path("/statistics")
public class StorageService {

    @Context
    private ServletContext application;

    StatisticsStorage statisticsStorage;

    @PostConstruct
    public void initialize() {
        System.out.println("In PostConstruct");
        try {
            statisticsStorage = new StatisticsStorage((String) application.getAttribute(AppProperties.PropKey.STATS_OUTPUT_PATH_PROP.toString()));
        } catch (Exception sqle) {
            sqle.printStackTrace();
        }
    }


    @GET
    // The Java method will produce content identified by the MIME Media type "text/plain"
    @Produces({MediaType.APPLICATION_JSON})
    public Domain getSnapshot() {}

谢谢

【问题讨论】:

    标签: java jakarta-ee jersey weblogic jax-rs


    【解决方案1】:

    Jersey 对每个请求都实例化该类。请注意,您可以使用 @Context 注释的大部分内容都是特定于请求的。您最好的选择是使您的 StatisticsStorage 字段静态并在第一次请求时对其进行初始化(需要同步)。也许是这样的:

    public StorageService(@Context ServletContext application) {
        super(servletConfig, request, httpServletRequest, uriInfo, httpHeaders, securityContext);
        synchronized (this.getClass()) {
            if (statisticsStorage == null) {
                try {
                    statisticsStorage = new StatisticsStorage((String) application.getAttribute(AppProperties.PropKey.STATS_OUTPUT_PATH_PROP.toString()));
                } catch (Exception sqle) {
                    sqle.printStackTrace();
                }
            }
        }
    }
    static StatisticsStorage statisticsStorage;
    

    【讨论】:

      【解决方案2】:

      JAX-RS 资源类的默认“范围”是每个请求的范围。我们还可以将类注册为单例。不同的 JAX-RS 实现可能有不同的实现方式。例如 Apache Wink 有一个@Scope(ScopeType.SINGLETON)。但唯一可移植的方法是使用javax.ws.rs.core.Application 子类。比如:

      @ApplicationPath("/api")
      public class MyApplication extends Application {
          @Override
          public Set<Class<?>> getClasses() {
          }
          @Override
          public Set<Object> getSingletons() {
              Set<Object> singletons = new HashSet<>();
              singletons.add(new StorageService());
              return singletons;
          }
      }
      

      getClasses() 中返回的所有内容都将是每个请求的资源。 getSingletons() 将返回“应用程序范围”的资源。 Jersey 永远不会尝试实例化该类,因此我们可以自己处理所有初始化。

      另一方面,您可能需要考虑,如果将此类设为单例是您真正想要的。这样做会导致资源类成为有状态的,您将需要处理任何并发问题。

      如果您只想在@PostConstruct 中创建StatisticsStorage,也许更好的选择是使用注入框架,例如Guice。这是good Guice example(s)。或者EE的CDI

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-13
        • 2021-01-02
        • 2014-01-01
        • 2013-06-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多