2

У меня есть контроллер:Как повторно инициализировать инъецируемый компонент в контроллере с помощью Guice?

public class MyController extends Controller { 

    private final AuthChecker authChecker; 

    @Inject 
    public MyController(AuthChecker authChecker) { 
     this.authChecker = authChecker; 
    } 

    public Promise<Result> index() throws BusinessException { 
     authChecker 
      .tokenValue(request().username()) 
      .execute() 
      .go(); 
     // bla bla bla 
    } 

} 

И у меня есть проблемы с AuthChecker, поскольку он сохраняет внутреннее состояние, которое не инициализируется между запросами. Инициализации этого класса делается в конструкторе, который выполняется только один раз, тогда как это не @Singleton

По Play's documentation:

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

Я хочу, чтобы каждый запрос подсказывал Гиису создать новый экземпляр. Как я могу решить эту проблему?

Кроме того, являются ли контроллеры одноточечными? Потому что они, кажется, созданы только один раз в течение всего жизненного цикла приложения.

Спасибо.

+1

Контроллеры одноэлементны действительно. Из-за этого на каждый контроллер создается только один экземпляр «AuthChecker». Другими словами, все запросы конкретного контроллера совместно используют один и тот же экземпляр 'authChecker'. Вы можете либо настроить [область] (https://github.com/google/guice/wiki/Scopes) «MyController», либо написать безстоящую версию «AuthChecker». ИМО второй подход является предпочтительным. – Roman

+0

Спасибо. Да, вторая кажется предпочтительной после прочтения вашей ссылки. Но уверены ли мы, что «Контроллеры» являются потокобезопасными? Что произойдет, если два запроса поступят в одно и то же время? – c4k

+1

Для прямого ответа на ваш вопрос введите «Provider » вместо простого «AuthChecker». –

ответ

1

Вы можете использовать поставщика, то есть Guice создает новый экземпляр (если не настроен иначе в вашем модуле) каждый раз, когда вы к нему доступ:

public class MyController extends Controller { 

    private final Provider<AuthChecker> authChecker; 

    @Inject 
    public MyController(Provider<AuthChecker> authChecker) { 
     this.authChecker = authChecker; 
    } 

    public Promise<Result> index() throws BusinessException { 
     authChecker.get() 
      .tokenValue(request().username()) 
      .execute() 
      .go(); 
     // bla bla bla 
    } 

} 
Смежные вопросы