在Java Jersey 2 JAX-RS中初始化单例

我是泽西岛的新手(2.22.2),请耐心等待。 我正在创建一个与LDAP服务器连接的REST服务,用于存储,删除和检索用户数据。 该服务通过执行加密/解密充当安全中介。

在使用REST服务之前必须进行相当多的初始化,并且我只想执行一次初始化(当应用程序部署在服务器上时)。 所以这项服务将作为单身人士运行。

如果有人可以给我一些关于最佳方法的指示,我将不胜感激吗? 谢谢!

用户Spring框架。

https://projects.spring.io/spring-framework/

https://jersey.java.net/documentation/latest/spring.html

这里有一个完整的工作示例:

https://github.com/jersey/jersey/tree/2.22.2/examples/helloworld-spring-webapp

你基本上将这个依赖项添加到你的jersey项目,它将自动包括Spring:

 org.glassfish.jersey.ext jersey-spring3 ${project.version}  

然后在名为applicationContext.xml和src / main / resources的文件中定义Spring Bean:

    

最后但同样重要的是,在您的实际资源中,您可以使用@Autowire注释注入此单例服务:

  @Path("/resource") @Component public class MyResource { @Autowired private MyService myService; @GET @Produces(MediaType.TEXT_PLAIN) public String getHello() { return myService.sayHello(); } } 

使用@SingletonResource并在资源中初始化状态是一个可怕的,可怕的想法IMO。 关注点分离很重要,将状态保存在REST资源中非常糟糕。 通过创建一个LDAPResource和一个LDAPService来分离处理您的接口(REST)和业务逻辑的代码。 Spring在这里播放的部分就是接线,否则你必须自己实例化。

Jersey 2.22.2具有内置支持,可以改变其资源的生命周期。 您可以使用@Singleton注释。 在JAX-RS应用程序,资源和子资源:根资源类的生命周期的官方文档中阅读它。 只需将初始化代码放在资源的默认构造函数中即可。

  • 范围:单身人士
  • 注释: @Singleton
  • 注释完整的类名: javax.inject.Singleton

在此范围内,每个jax-rs应用程序只有一个实例。 Singleton资源可以使用@Singleton注释,并且可以使用Application实例注册其类。 您还可以通过将单例实例注册到Application中来创建单例。

例:

 package com.airhacks; import java.util.Date; import javax.inject.Singleton; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("/hello") @Singleton public class HelloWorldService { public HelloWorldService() throws InterruptedException { // Some expensive initialization goes here. Thread.sleep(5000); System.out.println("Initialized at " + new Date()); } @GET public Response getMsg() { String output = "Hello world at " + new Date(); return Response.status(200).entity(output).build(); } } 

在上面的示例中,由于Glassfish 3上的延迟初始化,第一个请求花了五秒钟,然后立即提供所有后续请求。

您可以使用@Immediate而不是@Singleton ,以确保您的服务尽快启动。 曾经有一些问题,泽西岛没有默认启动立即上下文,但我认为现在已经解决了