in scope request injection bean spring ~ de lecture.

Création d'un bean de scope Request dans une application Spring

Vous vous rendez compte que pendant une même requête HTTP vous faites plusieurs fois les mêmes appels vers une source de données extérieure ? que ce soit un appel en base de données ou une appel à un webservice, il faut éviter de faire plusieurs fois ce genre d'appel coûteux.

Web Scopes

Bean scope "Request"

Un moyen simple est de créer un bean de scope "request" (valable uniquement dans un contexte web) : pour chaque requête HTTP une nouvelle instance du bean est crée et est accessible durant le cycle de vie de la requête, explications ici.

Voici la façon de s'y prendre avec le framework Spring :

/**
 * Utilitaire permettant de conserver les informations de session utilisateur pendant la requête HTTP en cours
 */
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST)
public class RequestSessionHelper {

    @Autowired
    private SessionService sessionService;

    private Session session;
    private Map<String, String> cookies;

    /**
     * Récupère la session courante, ne fait l'appel qu'une fois durant toute la requête HTTP
     */
    public Session getSession() {
        if (session == null) {
            session = sessionService.getSession(cookies);
        }
        return session;
    }

    public void saveCookies(Map<String, String> cookies) {
        this.cookies = cookies;
    }

    public Map<String, String> getCookies() {
        return cookies;
    }
}

Nous voyons que dans ce bean l'injection est possible (ici SessionService). Tout le long du cycle de vie de ce bean, la session sera récupérée qu'une seule fois via la méthode getSession().

Injection dans un Bean scope "Singleton"

L'injection du bean "RequestSessionHelper" dans un de vos services n'est malheureusement pas encore possible tel quel, il faut passer par un bean de scope "Singleton" qui servira d'intermédiaire en allant lui-même récupérer le bean de scope Request dans le contexte de l'application Spring :

/**
 * Gestionnaire de session utilisateur.
 * Permet de récupérer l'objet de scope request RequestSessionHelper dans le contexte Spring.
 */
@Component
public class RequestSessionManager implements ApplicationContextAware {

    ApplicationContext applicationContext;

    /**
     * RequestSessionHelper est de scope request
     */
    public RequestSessionHelper getSessionHelper() {
        return applicationContext.getBean(RequestSessionHelper.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

Cas d'utilisation

A présent il vous suffit d'injecter n'importe où dans votre projet le bean "RequestSessionManager" afin d'y récupérer la Session via le bean RequestSessionHelper (de scope Request) de la façon suivante :


...
    @Autowired
    private RequestSessionManager requestSessionManager;

    public void your_methode() {
        Session session = requestSessionManager.getSessionHelper().getSession();
        ...
    }
...