Инициализация синглтона в Java Джерси 2 JAX-RS

Я новичок в Джерси (2.22.2), так что терпите меня, пожалуйста. Я создаю службу REST, которая взаимодействует с сервером LDAP для хранения, удаления и извлечения пользовательских данных. Служба выступает в качестве посредника безопасности, выполняя шифрование / дешифрование.

Перед использованием REST-сервисов необходимо выполнить небольшую инициализацию, и я хотел бы выполнить эту инициализацию только один раз (когда приложение развернуто на сервере). Таким образом, этот сервис будет работать как синглтон.

Буду признателен, если кто-нибудь подскажет, как лучше всего это сделать? Спасибо!

3 ответа

Решение

Пользовательский Spring Framework.

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

Вы в основном добавляете эту зависимость в свой проект джерси, и он будет включать Spring автоматически:

        <dependency>
          <groupId>org.glassfish.jersey.ext</groupId>
          <artifactId>jersey-spring3</artifactId>
          <version>${project.version}</version>
        </dependency>

а затем вы определяете свои Spring Beans в файле с именем applicationContext.xml и src / main / resources:

<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 и инициализация состояния внутри ресурса - ужасная, ужасная идея IMO. Разделение проблем важно, и сохранение состояния в ресурсе REST просто ужасно. Разделите код, который работает с вашим интерфейсом (REST) ​​и вашей бизнес-логикой, создав, скажем, LDAPResource и LDAPService. Роль, которую играет здесь Spring, - это просто проводка, которую в противном случае вам бы пришлось создать для себя.

Джерси 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, чтобы обеспечить запуск вашего сервиса как можно скорее. Однажды была проблема, когда Джерси не запускал контекст Immediate по умолчанию, но я думаю, что это уже решено

Другие вопросы по тегам