Java 为什么泽西岛导致单身阶级不工作?

Java 为什么泽西岛导致单身阶级不工作?,java,jersey,singleton,Java,Jersey,Singleton,我实现了如下内容: @Path("/svc") public class Service { Resource rsc = Resource.getInstance(); @GET public String doGet() {...} } public class Resource { public static Resource instance; private Resource() {...} public static get

我实现了如下内容:

@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
类是实现
GET
POST
方法的地方,其中
Resource
是临时存储某些数据的单例类


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

您没有为实例变量赋值

public class Resource{
      private static Resource instance;

      private Resource(){...}

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

        }
        return instance;
      }    
}

因此,当您尝试
getInstance()
资源文件时。它始终为空,这将导致为类创建新对象,因为您没有为实例变量赋值

public class Resource{
      private static Resource instance;

      private Resource(){...}

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

        }
        return instance;
      }    
}

因此,当您尝试
getInstance()
资源文件时。它总是空的,这会导致为类创建新对象,JAX-WSWeb服务本身就是一个单例。这意味着所有请求都将使用单个web服务实例(如Servlet)进行处理。 参考此链接,详细答案已在此处

默认情况下,Jersey为每个请求创建资源类的新实例。因此,如果不注释Jersey资源类,它将隐式使用@RequestScope作用域。泽西岛文件中规定:

默认生命周期(不存在注释时应用)。在这个 范围为每个新请求创建并使用资源实例 用于处理此请求。如果资源被多个用户使用 在请求处理过程中,始终使用相同的实例。 当一个资源是子资源并且返回的次数更多时,就会发生这种情况 在配对过程中重复了三次。在这种情况下,只有在实例上才会出现 为请求提供服务器


JAX-WSWeb服务本身就是一个单例。这意味着所有请求都将使用单个web服务实例(如Servlet)进行处理。 参考此链接,详细答案已在此处

默认情况下,Jersey为每个请求创建资源类的新实例。因此,如果不注释Jersey资源类,它将隐式使用@RequestScope作用域。泽西岛文件中规定:

默认生命周期(不存在注释时应用)。在这个 范围为每个新请求创建并使用资源实例 用于处理此请求。如果资源被多个用户使用 在请求处理过程中,始终使用相同的实例。 当一个资源是子资源并且返回的次数更多时,就会发生这种情况 在配对过程中重复了三次。在这种情况下,只有在实例上才会出现 为请求提供服务器

简短回答 你的单身汉不是单身汉

答案很长,如何解决
实例
字段是
公共
,您总是返回一个新的
资源
实例,而不是将其分配给
实例
字段

还建议将类标记为
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;
    }
}
但是,这不是实现单例的最佳方式

有关更多信息,请参阅

简短回答 你的单身汉不是单身汉

答案很长,如何解决
实例
字段是
公共
,您总是返回一个新的
资源
实例,而不是将其分配给
实例
字段

还建议将类标记为
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;
    }
}
但是,这不是实现单例的最佳方式


有关更多信息,请参阅

您从未分配给
实例
@Thilo谢谢,这是一个愚蠢的错误…您从未分配给
实例
@Thilo谢谢,这是一个愚蠢的错误…还应将
实例
保密。考虑多线程访问。是的,您必须将其设置为私有。我刚刚添加了实例值来解决上述问题。获取的输入,谢谢@thiloss还应该使
实例
私有化。考虑多线程访问。是的,您必须将其设置为私有。我刚刚添加了实例值来解决上述问题。输入,谢谢@ThiloI,我不认为这是真的,除非你也用
@Singleton
注释。请参阅您链接到的答案评论中的讨论。我认为这不是真的,除非您还使用
@Singleton
进行注释。请参阅您链接到的答案评论中的讨论。谢谢,今天早上意识到。。。真是个愚蠢的错误。谢谢你提供的额外资源。谢谢你,意识到今天早上。。。真是个愚蠢的错误。谢谢你提供的额外资源。