在 Java Jersey 2 JAX-RS 中初始化单例
Initialize singleton in Java Jersey 2 JAX-RS
我是 Jersey (2.22.2) 的新手,所以请多多包涵。我正在创建一个与 LDAP 服务器接口的 REST 服务,用于存储、删除和检索用户数据。该服务通过执行 encryption/decryption.
充当安全中介
在使用 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:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>${project.version}</version>
</dependency>
然后在名为 applicationContext.xml 和 src/main/resources:
的文件中定义 Spring Beans
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="mySingletonService" class="com.test.MyService"/>
<beans/>
最后但同样重要的是,在您的实际资源中,您可以使用 @Autowire 注释注入此单例服务:
@Path("/resource")
@Component
public class MyResource {
@Autowired
private MyService myService;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getHello() {
return myService.sayHello();
}
}
在我看来,使用@SingletonResource 并在资源中初始化状态是一个非常糟糕的想法。关注点分离很重要,在 REST 资源中保持状态简直太糟糕了。通过创建比方说 LDAPResource 和 LDAPService 来分离处理接口 (REST) 和业务逻辑的代码。 Spring 在这里扮演的部分只是连接,否则你必须自己实例化。
Jersey 2.22.2 内置支持更改其资源的生命周期。您可以使用 @Singleton
注释。在 JAX-RS Application, Resources and Sub-Resources: Life-cycle of Root Resource Classes 的官方文档中阅读它。只需将您的初始化代码放入资源的默认构造函数中即可。
- Scope: Singleton
- Annotation:
@Singleton
- Annotation full class name:
javax.inject.Singleton
In this scope there is
only one instance per jax-rs application. Singleton resource can be
either annotated with @Singleton and its class can be registered using
the instance of Application. You can also create singletons by
registering singleton instances into 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,以确保您的服务尽快启动。曾经有一些问题 Jersey 默认情况下没有启动 Immediate 上下文,但我认为现在已经解决了
我是 Jersey (2.22.2) 的新手,所以请多多包涵。我正在创建一个与 LDAP 服务器接口的 REST 服务,用于存储、删除和检索用户数据。该服务通过执行 encryption/decryption.
充当安全中介在使用 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:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>${project.version}</version>
</dependency>
然后在名为 applicationContext.xml 和 src/main/resources:
的文件中定义 Spring Beans<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="mySingletonService" class="com.test.MyService"/>
<beans/>
最后但同样重要的是,在您的实际资源中,您可以使用 @Autowire 注释注入此单例服务:
@Path("/resource")
@Component
public class MyResource {
@Autowired
private MyService myService;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getHello() {
return myService.sayHello();
}
}
在我看来,使用@SingletonResource 并在资源中初始化状态是一个非常糟糕的想法。关注点分离很重要,在 REST 资源中保持状态简直太糟糕了。通过创建比方说 LDAPResource 和 LDAPService 来分离处理接口 (REST) 和业务逻辑的代码。 Spring 在这里扮演的部分只是连接,否则你必须自己实例化。
Jersey 2.22.2 内置支持更改其资源的生命周期。您可以使用 @Singleton
注释。在 JAX-RS Application, Resources and Sub-Resources: Life-cycle of Root Resource Classes 的官方文档中阅读它。只需将您的初始化代码放入资源的默认构造函数中即可。
- Scope: Singleton
- Annotation:
@Singleton
- Annotation full class name:
javax.inject.Singleton
In this scope there is only one instance per jax-rs application. Singleton resource can be either annotated with @Singleton and its class can be registered using the instance of Application. You can also create singletons by registering singleton instances into 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,以确保您的服务尽快启动。曾经有一些问题 Jersey 默认情况下没有启动 Immediate 上下文,但我认为现在已经解决了