Подтвердить что ты не робот

Когда использовать аннотацию @Singleton в Джерси?

Я разрабатываю веб-службу RESTful и, читая документацию в Джерси, наткнулся на аннотацию @Singleton

В моем веб-сервисе я в основном возвращаю данные на основе уникальных ключей, предоставляемых в качестве параметра. Аналогия будет возвращать всю информацию Студента при передаче Student_Id.

Итак, мой вопрос: когда @Singleton подходит для таких веб-сервисов?

Согласно документации для @RequestScoped

Если ресурс используется более одного раза в обработке запроса, всегда будет использоваться один и тот же экземпляр.

Тогда в этом случае мы не должны @Singleton использовать @Singleton правильно?

Также могут быть случаи использования, когда мы должны создать новый экземпляр для каждого запроса?

Я посмотрел этот пост, но на мой вопрос не ответил.

4b9b3361

Ответ 1

По умолчанию Джерси создает новый экземпляр класса ресурсов для каждого запроса. Поэтому, если вы не комментируете класс ресурсов Джерси, он неявно использует область @RequestScoped. В документация Джерси:

Жизненный цикл по умолчанию (применяется, если аннотация отсутствует). В этом scope экземпляр ресурса создается для каждого нового запроса и используется для обработки этого запроса. Если ресурс используется более одного времени в обработке запроса, всегда будет использоваться один и тот же экземпляр. Это может произойти, когда ресурс является дополнительным ресурсом, возвращается больше раз во время согласования. В этой ситуации только на сервера.

В большинстве случаев вы используете этот параметр по умолчанию, поэтому вы не используете область @Singleton. Вы также можете создать класс ресурса singleton Jersey, используя аннотацию @Singleton. Затем вам нужно зарегистрировать одноэлементный класс в классе MyApplication, например,

@Path("/resource")
@Singleton
public class JerseySingletonClass {
    //methods ...
}

public class MyApplication extends ResourceConfig {

    /*Register JAX-RS application components.*/
    public MyApplication () {
        register(JerseySingletonClass.class);
    }
}

Ответ 2

В большинстве случаев @RequestScoped умолчанию @RequestScoped должен быть достаточным для ваших нужд.

@Singleton может находиться в состоянии. У меня возникла проблема, когда моя конечная точка была аннотирована как @Singleton поэтому она повторно использовала тот же EntityManager во время одновременных вызовов. После удаления @Singleton во время одновременных вызовов используются разные экземпляры объектов EntityManager. Если последующие вызовы конечной точки, возможно, будет использоваться предыдущий/старый EntityManager. - Джерси, Guice и Hibernate - Безопасность потока EntityManager

Ответ 3

На самом деле используется прецедент, описанный в руководстве "Джерси-2" для использования SseBroadcaster при обслуживании событий Server-Sent, в этом приведенном примере

Класс ресурсов BroadcasterResource аннотируется аннотацией @Singleton, в которой указано, что для выполнения всех входящих запросов в/широковещательный канал используется только один экземпляр класса ресурсов. Это необходимо, так как мы хотим сохранить единую ссылку на приложение для частного вещательного поля, чтобы мы могли использовать один и тот же экземпляр для всех запросов. Клиенты, которые хотят прослушивать события SSE, сначала отправляют запрос GET в BroadcasterResource, который обрабатывается методом ресурса listenToBroadcast().

Используя @Singleton, приложение будет содержать только один SseBroadcaster для всех входящих запросов, одного такого вещателя достаточно, чтобы обслуживать несколько клиентов, поэтому его нужно создать только один раз!

JAX-RS SSE API определяет SseBroadcaster, который позволяет передавать отдельные события нескольким клиентам.

Ответ 4

Я пришел к этому вопросу, потому что впервые у меня был случай, когда я не использовал аннотацию @Singleton.

Singleton - это шаблон проектирования, его следует использовать, если:

  • Объект, который вы "одиночка", сохраняет состояние, которое должно быть общим и уникальным (пример: глобальный счетчик)
  • Обычно я разрабатываю REST API без сохранения состояния, все обрабатывается в методе (полное закрытие): поэтому, как правило, все мои ресурсы являются одиночными (вариант использования: лучшая производительность)

Тем не менее, сегодня я нашел этот вариант использования для того, чтобы не использовать Singleton:

@Path("/someendpoint/{pathparam}/somethingelse/")
//@Singleton
public class MyResource {
    @PathParam("pathparam")
    private String pathparam;
}

Используя это, я привязываю параметр path к своему экземпляру, поэтому он должен быть RequestScoped. В общем, я бы поместил аннотацию @PathParam в каждый метод, поэтому @Singleton был бы прав в классе.

Я не уверен в производительности, однако создание и уничтожение объекта не является бесплатной операцией.