Каков наилучший способ внедрения одноэлементного сервиса в ресурс JAX-RS / Jersey? - PullRequest
0 голосов
/ 18 апреля 2020

Например, что если нескольким конечным точкам ресурсов требуется доступ к некоторой шине сообщений для обработки запросов? Конечно, есть какой-то способ зарегистрировать одноэлементный класс обслуживания и внедрить его в ресурсы, когда сам класс обслуживания НЕ является ресурсом, а используется ресурсами.
Все примеры, которые я видел с поставщиками или пользовательскими привязками HK2, относятся к ресурсам.

Самое близкое, что я нашел к тому, что я искал, было с этим вопросом:
Проблема при создании простого одноэлементного класса в Джерси 2 с использованием встроенного внедрения зависимости Джерси

Как лучше всего это сделать с помощью JAX-RS / Jersey?

Обратите внимание, что способ программирования c был бы наиболее полезным, я не использую файл xml для настройки сервера.

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Если ваша платформа поддерживает EJB, вы можете использовать @Singleton EJB (пакет javax.ejb, а не javax.inject) и добавить его в свои ресурсы с помощью аннотации @EJB. В Singleton EJB также есть контроль параллельного доступа outofthebox.

На простом Джерси вы можете использовать контекст приложения CDI. Объявите класс обслуживания с аннотацией @ApplicationScoped и добавьте его в свои ресурсы с помощью @Inject. CDI будет создавать только один компонент.

Если вы не можете аннотировать класс обслуживания, вы можете создать метод, который предоставляет вашей реализации сервиса аннотирование его @Produces и @ApplicationScoped.

@Produces
@ApplicationScoped
public MyService produceService() {
    // instantiate your service client
}

А затем используйте его на своих ресурсах с:

@Inject
private MyService
0 голосов
/ 20 апреля 2020

Ответ за кредит отправляется на @areus ответ, приведенный здесь .
Однако я предоставляю свой собственный ответ, чтобы я мог поделиться кодом.

Служебный компонент

@Singleton
public final class MyServiceBean
{
  private static final AtomicInteger INSTANCES = new AtomicInteger();
  private final AtomicInteger calls = new AtomicInteger();

  public MyServiceBean()
  {
    INSTANCES.incrementAndGet();
  }

  public String getMessage()
  {
    return String.format("MyServiceBean{INSTANCES=%d, CALLED=%d}", INSTANCES.get(), calls.incrementAndGet());
  }
}

Класс ресурса

@Path("/messages")
public final class MyResource
{
  @Inject
  private MyServiceBean bean;

  @GET
  @Produces(MediaType.TEXT_PLAIN)
  public Response handle()
  {
    return Response.ok(this.bean.getMessage())
      .type(MediaType.TEXT_PLAIN_TYPE)
      .build();
  }
}

HK2 Binder

public final class MyServiceBeanBinder extends AbstractBinder
{
  @Override
  protected void configure()
  {
    bind(MyServiceBean.class).to(MyServiceBean.class).in(Singleton.class);
  }
}

Затем просто зарегистрируйте подшивку и ресурс следующим образом:

final ResourceConfig config = new ResourceConfig();
config.register(MyResource.class);
config.register(new MyServiceBeanBinder());

Запуск сервера и многократное попадание на ресурс приводит к:

MyServiceBean{INSTANCES=1, CALLED=1}   
MyServiceBean{INSTANCES=1, CALLED=2}   
MyServiceBean{INSTANCES=1, CALLED=3}   
MyServiceBean{INSTANCES=1, CALLED=4}   
MyServiceBean{INSTANCES=1, CALLED=5}
...