【问题标题】:Why does Jersey cause singleton class not working?为什么泽西岛会导致单例课程不起作用?
【发布时间】:2015-11-20 04:52:33
【问题描述】:

我实现了这样的东西:

@Path("/svc")
public class Service {

    Resource rsc = Resource.getInstance();

    @GET
    public String doGet() {...}
}

public class Resource {

    public static Resource instance;

    private Resource() {...}

    public static getInstance(){
        if (instance == null){
            return new Resource();
        }
        return instance;
    }
}

Service 类是实现GETPOST 方法的地方,其中Resource 是临时存储一些数据的单例类。

但是,当我测试它时,我发现单例类在每次调用方法时都会获得一个新实例。单例类只是一个经典的 Java 单例实现。我知道添加 @Singleton 注释可以解决问题,但我想知道是什么导致了这种行为?

【问题讨论】:

  • 你永远不会分配给instance
  • @Thilo 谢谢,这是一个愚蠢的错误......

标签: java jersey singleton


【解决方案1】:

简答

你的单身不是单身

长答案以及如何解决它

instance 字段是 public,您总是返回一个新的 Resource 实例,而不是将其分配给 instance 字段。

还建议将您的课程标记为 final 并在您的 getInstance() 方法中使用同步:

public final class Resource {

    private static Resource instance;

    private Resource() {

    }

    public static synchronized Resource getInstance() {
        if (instance == null) {
            instance = new Resource();
        }
        return instance;
    }
}

但是,这不是实现单例的最佳方式

更多信息,请参考What is an efficient way to implement a singleton pattern in Java?

【讨论】:

  • 谢谢,今天早上意识到……真是个愚蠢的错误。感谢您提供额外的资源。
【解决方案2】:

您没有为实例变量赋值。

public class Resource{
      private static Resource instance;

      private Resource(){...}

      public static getInstance(){
        if(instance == null){
    instance = new Resource();

        }
        return instance;
      }    
}

所以,当您尝试getInstance() 的资源文件时。它始终为 null,这会导致为类创建新对象

【讨论】:

  • 也应该将instance设为私有。并考虑多线程访问。
  • 是的,你必须做到private。我刚刚添加了实例值来解决问题中提到的问题。输入,感谢@Thilo
【解决方案3】:

JAX-WS Web 服务本身就是一个单例。这意味着所有请求都将使用单个 Web 服务实例(如 Servlet)来处理。 请参阅此链接,详细答案已经在这里Singleton Object in Java Web service

默认情况下,Jersey 会为每个请求创建一个资源类的新实例。因此,如果您不注释 Jersey 资源类,它会隐式使用 @RequestScoped 范围。泽西岛文档中有说明:

默认生命周期(在不存在注释时应用)。在这个 范围为每个新请求创建资源实例并使用 用于处理此请求。如果资源被使用多个 在请求处理的时间里,总是会使用同一个实例。 当资源是子资源返回更多时,可能会发生这种情况 匹配期间的次数。在这种情况下,只有实例会 处理请求。

【讨论】:

  • 我不认为这是真的,除非你也用@Singleton 注释。请参阅 cmets 中有关您链接到的答案的讨论。
猜你喜欢
  • 2015-09-19
  • 1970-01-01
  • 2013-08-12
  • 2015-08-11
  • 2017-09-18
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多