2017-08-14 4 views
1

Est-il possible d'utiliser des beans scope "session" avec Spring Session et Pivotal GemFire?Les beans scope de session peuvent-ils être utilisés avec Spring Session et GemFire?

Lors de l'utilisation Session de printemps pour les haricots de portée "session", Spring crée un HttpSession supplémentaire pour ce haricot. Est-ce un problème existant?

Quelle est la solution pour cela?

+0

Une solution pour la requête ci-dessus? –

+0

Vous avez des questions sur la solution et répondez ci-dessous? –

+0

1 dernier commentaire ... J'ai construit un exemple dans la dernière version de _Spring Session Data GemFire_, * 2.0.0.RC1 * (vient de sortir hier ... https://spring.io/blog/2017/11/ 07/spring-session-data-geode-gemfire-2-0-0-rc1-available) qui montre comment fonctionnent les proxies de Spring "_session_" dans le contexte d'une application _Spring Boot_ configurée avec _Spring Session_ (en utilisant GemFire ​​/ Geode comme le fournisseur). Voir ici ... https: //docs.spring.io/autorepo/docs/spring-session-data-geode-build/2.0.0.RC1/reference/html5/guides/boot-gemfire-with-scoped-proxies .html –

Répondre

3

En ce qui concerne ...

session Can scopes les haricots être utilisés avec du printemps et GemFire?

Oui!

En fait, peu importe quel «fournisseur» sous-jacent est utilisé avec Spring Session non plus. Par exemple, Spring Session with GemFire/Geode (docs) ou Spring Session with Redis (docs), etc, peuvent être utilisés et cela fonctionnera de la même façon (de la même manière).

En ce qui concerne ...

Si vous utilisez la session de printemps pour la session SCOPED haricots printemps crée HttpSession supplémentaire pour ce haricot, est-ce un problème existant?

Eh bien, cela est pas exactement vrai.

Vous devez comprendre les technologies sous-jacentes en jeu ici et la façon dont ils travaillent tous ensemble, y compris session de printemps, le Spring Framework, le cadre Servlet, votre conteneur Web (par exemple Tomcat), qui est lié par le contrat spécifié dans la spécification Java EE Servlet et toutes les autres technologies que vous avez éventuellement appliquées (par exemple Support Web de Spring Security).

Si nous plonger profondément dans architecture de printemps/infrastructure, vous commencerez à comprendre comment cela fonctionne, pourquoi il fonctionne et pourquoi votre déclaration particulière (« Spring crée une supplémentaire HttpSession pour ce haricot ») est pas correct.

Première, session de printemps enregistre un tout important ServletFilter, le o.s.session.web.http.SessionRepositoryFilter.

Il existe de nombreuses façons de le faire, et le Javadoc pour javax.servlet.Filter hints essentiellement que cela se fait via le Web Application « descripteur de déploiement ».

Bien sûr, compte tenu de notre ménagerie d'options de configuration aujourd'hui, un descripteur de déploiement d'application Web est assez vaguement défini, mais nous savons que souvent cela signifie web.xml. Cependant, ce n'est pas la seule façon dont nous pouvons configurer, essentiellement, les ServletContext de l'application Web.

Spring prend en charge les base web.xmldescripteurs de déploiement ainsi que JavaConfig utilisant le Servlet (3.0+) API.

Dans web.xml vous le feriez register (pour example) le Cadres printempso.s.web.filter.DelegatingFilterProxy, que les délégués à une mise en œuvre javax.servlet.Filter réelle (lors session de printemps est en jeu, ce serait le o.s.session.web.http.SessionRepositoryFilter, bien sûr) qui est aussi déclaré/défini comme "bean" (premier this, puis this) dans le conteneur Spring. Cela est nécessaire pour fil automatique (injection) la session de printempso.s.session.SessionRepository de mise en œuvre appropriée (également Spring managed bean défini dans le conteneur, par exemple pour Redis) qui sait déléguer (HTTP) Session la gestion de l'Etat à la "fournisseur" sous-jacent.

Dans le JavaConfig approche, l'enregistrement est effectué par le noyau concept Spring Frameworko.s.web.WebApplicationInitializer. Lisez le Javadoc pour plus de détails.

Eh bien, session de printemps fournit une telle gestion de session WebApplicationInitializer pour initialiser (HTTP), le o.s.session.web.context.AbstractHttpSessionApplicationInitializer. En règle générale, lors de l'utilisation printempsJava-based Container Configuration et/ou approche Annotation configuration, un développeur créerait une classe qui étend cette session de printemps classe fournie et register la configuration nécessaire (par exemple des critères de connexion) pour le fournisseur de gestion de session sous-jacente; pour example (voir aussi this). La classe Config est annotated avec @EnableRedisHttpSession qui imports la Spring@Configuration classe qui déclare/définit la appropriée Session de printempsSessionRepository mise en œuvre du « fournisseur » (par exemple à nouveau Redis), qui est nécessaire par le ServletFilter (encore une fois SessionRepositoryFilter).

Si vous regardez ce que la session de printempsAbstractHttpSessionApplicationInitializer fait, vous verrez qu'il registers la session de printemps, SessionRepositoryFilter, indirectement par l'intermédiaire de Spring FrameworkDelegatingFilterProxy ... d'insertion, puis here, puis here et enfin, here.

Comme vous pouvez le voir, la session de printempsSessionRepositoryFilter est positioned first dans la chaîne de ServletFilters. Le !insertBeforeOtherFilters est annulé puisque le paramètre dans javax.servlet.FilterRegistration.Dynamic.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns...) est "isMatchAfter".

Cela est essentiel, puisque la de la session de printemps o.s.session.web.http.SessionRepositoryFilterreplaces à la fois du javax.servlet.http.HttpServletRequest et javax.servlet.http.HttpServletResponse. Plus précisément, en remplaçant la javax.servlet.http.HttpServletRequest, session de printemps peut fournir une implémentation de javax.servlet.http.HttpSession (quand HttpServletRequest.getSession(..) est appelé) qui est soutenu par Session de printemps et le fournisseur de choix du promoteur (par exemple Redis, GemFire), le but de l'En premier lieu Session en premier lieu.

Ainsi, le ServletFilters voir la requête HTTP/réponse avant que le code-cadre (par exemple session de cadre de printemps scope infrastructures de haricot), et surtout avant tout des applications Web de Controllers ou Servlets, obtenez de voir HTTP demande de réponse.

Ainsi, lorsque le noyau session Spring Framework scope infrastructure haricot voit le (HTTP) Servlet demande/réponse, il voit ce session de printemps remis, ce qui est juste une mise en œuvre des javax.servlet régulières interfaces (par exemple HttpSession) soutenu par Session de printemps.

En regardant le noyau de mise en œuvre « personnalisée » de Spring Frameworko.s.web.context.request.SessionScope (qui gère les références de haricots/cycles de vie de haricots pour la session scopes haricots déclarés/définis dans le ressort récipient), qui étend o.s.web.context.request.AbstractRequestAttributesScope, vous voyez que ce seulement les délégués à la classe o.s.web.context.request.SessionRequestAttributes. Cette classe est créée principalement par SpringDispatcherServlet, et définit toutes ses opérations (par exemple) en termes de portée «fournie» définie par le bean (définition) en question. Voir le source pour plus de détails. Ainsi, le bean est ajouté à la session HTTP appropriée.

Bien sûr, Spring"will" create a newjavax.servlet.http.HttpSession sur la première requête HTTP, mais non sans infrastructure de la session de printemps savoir à ce sujet, puisque ce Spring utilise dans ce cas est une implémentation de javax.servlet.http.HttpSession soutenu par Session de printemps de "Session".

En outre, getSession(true) est également juste une indication que le HttpSession est « permis » à créer si elle n'existe pas déjà! Un conteneur Servlet ne crée simplement pas de nouvelles sessions HTTP pour chaque requête HTTP, tant que l'ID de session peut être déterminé à partir de la requête HTTP (par injection d'URL ... jsessionid ou avec un cookie, généralement) .Voir le javax.servlet.HttpServletRequest.getSession(boolean) pour plus de détails.

Quoi qu'il en soit, la seule mise en garde à toute cette histoire est, vous devez vous assurer, en particulier pour GemFire ​​que ...

  1. Le printemps « session » scope beans définis dans le récipient sont sérialisables, soit en utilisant Java Serialization, soit en 1 sur GemFire's serialization strategies. Cela inclut toutes les références du bean (autres beans, types d'objets, etc.) à moins que ces "références" ne soient déclarées transient. NOTE: Je ne suis pas entièrement certain que la méthode de sérialisation PDX basée sur GemFire ​​Reflection est entièrement "consciente" des champs "transitoire". Soyez conscient de cela.

  2. Vous devez vous assurer que les classes sérialisées de la session se trouvent sur le chemin de classes GemFire ​​Servers.

Je suis working on a configuration option pour la session de printemps de données Geode/GemFire ​​au moment de soutenir PDX, mais c'est pas encore disponibles.

De toute façon, j'espère que cela aidera à éclaircir un peu les eaux boueuses. Je sais que c'est beaucoup à digérer, mais tout devrait fonctionner comme l'utilisateur l'attend.

J'ajouterai aussi que je n'ai pas testé cela non plus. Cependant, après avoir examiné le code, je suis à peu près certain que cela devrait fonctionner. J'ai made it a task pour ajouter des tests et des échantillons pour couvrir cette situation dans un proche avenir.

À la votre! -John