2017-01-05 5 views
1

У меня есть класс Controller, который является одноэлементным из-за аннотации Guice. Когда я расширяю этот класс другим классом singleton, я получаю новый List, в то время как из аннотации должно быть только 1. Вот код Controller:(Guice) Расширение singleton class делает отдельные списки

@Singleton 
public class Controller extends HttpServlet { 

    @Inject protected IAccountService accountService; 
    @Inject protected ITalenService talenService; 
    @Inject protected List<IAppGegevensService> appGegevensServices; 
    @Inject protected List<ITalenService> talenServices; 

Я знаю, что у меня есть два ITalenServices, но это из-за другую причину. Мой модуль содержит этот кусок кода:

@Singleton @Provides 
List<IAppGegevensService> provideAppGegevensServices() { 
    return new ArrayList<>(); 
} 

@Singleton @Provides 
List<ITalenService> provideTalenServices() { 
    return new ArrayList<>(); 
} 

Вот код класса, который расширяет Controller и устанавливает списки:

@Singleton 
public class MaakNieuweAppController extends Controller { 

    @Override 
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    req.setAttribute("talen", talenService.getAlleTalen()); 
    addAppGegevensService(accountService.findAccount((String) req.getSession().getAttribute("email"))); 
    addTalenService(accountService.findAccount((String) req.getSession().getAttribute("email"))); 
    req.getRequestDispatcher("kiezenTalen.jsp").forward(req, resp); 
    } 

} 

Вот код класса, который запрашивает одно из значений в списках:

@Singleton 
@MultipartConfig 
public class AlgemeneGegevensController extends Controller { 

    private Account account; 
    private IAppGegevensService appGegevensService; 

    @Override 
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    account = accountService.findAccount((String) req.getSession().getAttribute("email")); 
    appGegevensService = getAppGegevensService(account); 

Как только я добавить объект в список appGegevensServices или talenServices и попросить список I n другой класс (или один конкретный экземпляр в этом списке) он равен нулю. Как я могу убедиться, что есть только 1 список?

+0

«Я получаю новый список, а там должен быть только 1 из аннотации» Вы поняли, что '@ Singleton' делает: он просто подсказывает только, чтобы создать один экземпляр этого конкретного класса при привязке. Если у вас есть экземпляр 'Controller' и один из' MaakNieuweAppController', 'Controller' не является одиночным, потому что есть два его экземпляра. –

+0

Я понимаю, что он подсказывает, как создать один экземпляр класса, но тогда должен быть только один список слишком прав? И почему контроллер не является одиночным? Это должно быть из-за аннотации, или я ошибаюсь? ^^ – Sjoerd

+0

Word of advise: Если вы используете инъекцию поля (добавьте аннотацию к атрибутам), будьте очень осторожны, что вы делаете внутри своего конструктора. У вас нет доступа к инъецированным бобам здесь! В вашем примере вы не обращаетесь к ним, но если вам нужно инициализировать материал в конструкторе, лучше всего использовать инъекцию конструктора. –

ответ

0

получить новый список, а там должен быть только 1 из аннотации

Вы поняли, что @Singleton делает: он просто говорит Guice создать только один экземпляр определенного класса при связывании.

Если вы создали экземпляр Controller и экземпляр MaakNieuweAppController «вручную», вы, надеюсь, не ожидали, что они разделит экземпляр списка - и это не так, когда Guice создает их. Guice просто повторно использует один и тот же экземпляр Controller снова и снова и тот же экземпляр MaakNieuweAppController снова и снова.

(Обратите внимание, что если у вас есть экземпляр Controller и один из MaakNieuweAppController, Controller не одноэлементно в любом случае, потому что есть два экземпляра этого.)

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

public class Controller extends HttpServlet { 
    @Inject 
    protected List<IAppGegevensService> appGegevensServices; 

} 

, а затем

@Provides @Singleton 
List<IAppGegevensService> provideList() { ... } 

(или же вы хотите, чтобы обеспечить его)

+0

Спасибо за ваш ответ Энди! Я студент, и я новичок в Guice, поэтому мне нелегко узнать, где разместить метод enableList. Должно ли это быть в Контроллере? И где я должен назвать этот метод? Опять же, я новичок в этом. :) – Sjoerd

+0

Он должен быть в вашем модуле. –

+0

Извините, я не понимаю, что вы имеете в виду. – Sjoerd