2017-01-05 1 views
1

J'ai une classe Controller qui est singleton à cause de l'annotation de Guice. Lorsque j'étend cette classe avec une autre classe singleton, j'obtiens une nouvelle liste alors qu'il ne devrait y en avoir qu'une à cause de l'annotation. Voici le code de Controller:(Guice) L'extension de la classe singleton fait des listes séparées

@Singleton 
public class Controller extends HttpServlet { 

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

Je sais que j'ai deux ITalenServices, mais c'est une autre raison. Mon module contient ce morceau de code:

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

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

Voici le code d'une classe qui étend Controller et établit les listes:

@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); 
    } 

} 

Voici le code d'une classe qui demande l'une des valeurs dans les listes:

@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); 

dès que j'ajouter un objet à la liste appGegevensServices ou talenServices et demander la liste i Dans une autre classe (Ou une instance spécifique dans cette liste), elle est nulle. Comment puis-je m'assurer qu'il n'y a qu'une seule liste?

+0

« Je reçois une nouvelle liste alors qu'il ne devrait y avoir 1 en raison de l'annotation » mal compris ce que '@ Singleton' fait: il dit simplement à guice de créer une seule instance de cette classe spécifique quand elle est liée. Si vous avez une instance de 'Controller' et une de' MaakNieuweAppController', 'Controller' n'est pas un singleton, car il y en a deux instances. –

+0

Je comprends qu'il dit à guice de créer une instance de la classe, mais alors il ne devrait y avoir qu'une seule liste à droite? Et pourquoi Controller n'est-il pas un singleton? Cela devrait être à cause de l'annotation, ou ai-je tort? ^^ – Sjoerd

+0

Mot de l'avis: Si vous utilisez l'injection de champ (injection d'annotation sur les attributs), faites très attention à ce que vous faites dans votre constructeur. Vous n'avez pas accès aux grains injectés ici! Dans votre exemple, vous n'y accédez pas, mais si vous avez besoin d'initialiser des éléments dans le constructeur, il est préférable d'utiliser également l'injection de constructeur. –

Répondre

0

je reçois une nouvelle liste alors qu'il ne devrait y avoir 1 en raison de l'annotation

Vous comprenez mal ce @Singleton fait: il indique simplement Guice seulement de créer une instance de cette classe spécifique lorsqu'elle est liée.

Si vous avez créé une instance de Controller et une instance de MaakNieuweAppController "à la main", vous ne vous attendez pas à ce qu'ils partagent l'instance de liste - et ce n'est pas différent lorsque Guice les crée. Guice réutilise simplement la même instance de Controller encore et encore, et la même instance de MaakNieuweAppController encore et encore.

(Notez que si vous avez une instance de Controller et l'un des MaakNieuweAppController, Controller n'est pas un singleton de toute façon, parce qu'il ya deux exemples.)

Si vous voulez partager une liste , vous devez injecter l'instance de liste et vous assurer qu'elle est liée à une instance singleton.

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

} 

puis

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

(ou comme vous voulez fournir)

+0

Merci pour votre réponse Andy! Je suis un étudiant et je suis nouveau avec Guice, donc c'est un peu difficile pour moi de savoir où placer la méthode provideList. Devrait-il être dans le contrôleur? Et où devrais-je appeler cette méthode? Encore une fois, je suis nouveau avec ça. :) – Sjoerd

+0

Il devrait être dans votre module. –

+0

Désolé je ne comprends pas ce que vous voulez dire – Sjoerd