在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 ,以确保您的服务尽快启动。 曾经有一些问题,泽西岛没有默认启动立即上下文,但我认为现在已经解决了