Commit 14f7073f6feeb873448d858c0b2c7c7fbd32764c
1 parent
cc2a48d7
[FWK-205] Otimizado processo para associar beans de escopo de visão
diretamente a sessão (antes apenas uma referência era mantida na sessão). Assim objetos estão diretamente atrelados ao ciclo de vida da sessão e são destruídos corretamente no fim da sessão.
Showing
4 changed files
with
37 additions
and
34 deletions
Show diff stats
impl/extension/jsf/src/main/java/br/gov/frameworkdemoiselle/internal/context/FacesViewContextImpl.java
| ... | ... | @@ -36,7 +36,6 @@ |
| 36 | 36 | */ |
| 37 | 37 | package br.gov.frameworkdemoiselle.internal.context; |
| 38 | 38 | |
| 39 | -import java.util.concurrent.ConcurrentHashMap; | |
| 40 | 39 | import java.util.concurrent.atomic.AtomicLong; |
| 41 | 40 | |
| 42 | 41 | import javax.enterprise.context.ApplicationScoped; |
| ... | ... | @@ -70,23 +69,24 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC |
| 70 | 69 | |
| 71 | 70 | private final AtomicLong atomicLong = new AtomicLong(); |
| 72 | 71 | |
| 73 | - private ConcurrentHashMap<String, FacesViewBeanStore> sessionBeanStore = new ConcurrentHashMap<String, FacesViewBeanStore>(); | |
| 74 | - | |
| 72 | + //private ConcurrentHashMap<String, FacesViewBeanStore> sessionBeanStore = new ConcurrentHashMap<String, FacesViewBeanStore>(); | |
| 73 | + | |
| 75 | 74 | private static final String FACES_KEY = FacesViewContextImpl.class.getCanonicalName(); |
| 76 | - | |
| 75 | + private static final String VIEW_STORE_KEY = FacesViewBeanStore.class.getCanonicalName(); | |
| 76 | + | |
| 77 | 77 | public FacesViewContextImpl() { |
| 78 | 78 | super(ViewScoped.class); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | @Override |
| 82 | 82 | protected boolean isStoreInitialized() { |
| 83 | - return FacesContext.getCurrentInstance()!=null && getSessionId()!=null; | |
| 83 | + return FacesContext.getCurrentInstance()!=null && getSession()!=null; | |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | @Override |
| 87 | 87 | protected BeanStore getStore() { |
| 88 | - String sessionId = getSessionId(); | |
| 89 | - if (sessionId == null){ | |
| 88 | + HttpSession session = getSession(); | |
| 89 | + if (session == null){ | |
| 90 | 90 | return null; |
| 91 | 91 | } |
| 92 | 92 | |
| ... | ... | @@ -108,16 +108,16 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC |
| 108 | 108 | } |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | - | |
| 111 | + | |
| 112 | 112 | //A mesma técnica de bloqueio de thread acima é usada aqui para |
| 113 | 113 | //criar um SessionBeanStore caso o mesmo ainda não exista. |
| 114 | - FacesViewBeanStore currentStore = sessionBeanStore.get(sessionId); | |
| 114 | + FacesViewBeanStore currentStore = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); | |
| 115 | 115 | if (currentStore==null){ |
| 116 | 116 | synchronized (this) { |
| 117 | - currentStore = (FacesViewBeanStore) sessionBeanStore.get(sessionId); | |
| 117 | + currentStore = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); | |
| 118 | 118 | if (currentStore==null){ |
| 119 | 119 | currentStore = new FacesViewBeanStore(); |
| 120 | - sessionBeanStore.put(sessionId, currentStore); | |
| 120 | + session.setAttribute(VIEW_STORE_KEY, currentStore); | |
| 121 | 121 | } |
| 122 | 122 | } |
| 123 | 123 | } |
| ... | ... | @@ -129,22 +129,18 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC |
| 129 | 129 | * Called before the session is invalidated for that user. |
| 130 | 130 | * Destroys all view scoped beans stored on that session. |
| 131 | 131 | */ |
| 132 | - private void clearInvalidatedSession(String sessionId){ | |
| 133 | - if (sessionId != null){ | |
| 134 | - final FacesViewBeanStore store = sessionBeanStore.get(sessionId); | |
| 132 | + private void clearInvalidatedSession(HttpSession session){ | |
| 133 | + if (session != null){ | |
| 134 | + FacesViewBeanStore store = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); | |
| 135 | 135 | if (store!=null){ |
| 136 | + session.removeAttribute(VIEW_STORE_KEY); | |
| 136 | 137 | store.clear(this); |
| 137 | - sessionBeanStore.remove(sessionId); | |
| 138 | 138 | } |
| 139 | 139 | } |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | - /* | |
| 143 | - * Returns the current session ID. Creates a session if one doesn't exist. Returns NULL if the session can't be created. | |
| 144 | - */ | |
| 145 | - private String getSessionId(){ | |
| 146 | - final HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true); | |
| 147 | - return session!=null ? session.getId() : null; | |
| 142 | + private HttpSession getSession(){ | |
| 143 | + return (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true); | |
| 148 | 144 | } |
| 149 | 145 | |
| 150 | 146 | /** |
| ... | ... | @@ -162,11 +158,11 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC |
| 162 | 158 | * Destroys all view scoped beans stored on that session. |
| 163 | 159 | */ |
| 164 | 160 | protected void clearInvalidatedSession(@Observes BeforeSessionDestroyed event){ |
| 165 | - String sessionId = event.getSessionId(); | |
| 161 | + HttpSession session = event.getSession(); | |
| 166 | 162 | try{ |
| 167 | 163 | Context context = Beans.getBeanManager().getContext(ViewScoped.class); |
| 168 | 164 | if ( FacesViewContextImpl.class.isInstance(context) ){ |
| 169 | - ((FacesViewContextImpl)context).clearInvalidatedSession(sessionId); | |
| 165 | + ((FacesViewContextImpl)context).clearInvalidatedSession(session); | |
| 170 | 166 | } |
| 171 | 167 | } |
| 172 | 168 | catch(ContextNotActiveException ce){ | ... | ... |
impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java
| 1 | 1 | package br.gov.frameworkdemoiselle.lifecycle; |
| 2 | 2 | |
| 3 | +import javax.servlet.http.HttpSession; | |
| 4 | + | |
| 3 | 5 | /** |
| 4 | 6 | * This interface represents an event fired after a new HTTP session is created. |
| 5 | 7 | * |
| ... | ... | @@ -10,8 +12,8 @@ public interface AfterSessionCreated { |
| 10 | 12 | |
| 11 | 13 | /** |
| 12 | 14 | * |
| 13 | - * @return The ID of the recently created session | |
| 15 | + * @return The recently created session | |
| 14 | 16 | */ |
| 15 | - public String getSessionId(); | |
| 17 | + public HttpSession getSession(); | |
| 16 | 18 | |
| 17 | 19 | } | ... | ... |
impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/BeforeSessionDestroyed.java
| 1 | 1 | package br.gov.frameworkdemoiselle.lifecycle; |
| 2 | 2 | |
| 3 | +import javax.servlet.http.HttpSession; | |
| 4 | + | |
| 3 | 5 | /** |
| 4 | 6 | * This interface represents an event fired before an HTTP session is destroyed. |
| 5 | 7 | * |
| ... | ... | @@ -9,9 +11,14 @@ package br.gov.frameworkdemoiselle.lifecycle; |
| 9 | 11 | public interface BeforeSessionDestroyed { |
| 10 | 12 | |
| 11 | 13 | /** |
| 14 | + * <p>When calling this method the session still hasn't been invalidated so | |
| 15 | + * you can access attributes that are about to be removed from the session.</p> | |
| 16 | + * | |
| 17 | + * <p>Don't call {@link HttpSession#invalidate()} on the returned session, this operation | |
| 18 | + * is unsupported.</p> | |
| 12 | 19 | * |
| 13 | - * @return The session ID of the session about to be destroyed | |
| 20 | + * @return The session about to be destroyed | |
| 14 | 21 | */ |
| 15 | - public String getSessionId(); | |
| 22 | + public HttpSession getSession(); | |
| 16 | 23 | |
| 17 | 24 | -} |
| 25 | +} | |
| 18 | 26 | \ No newline at end of file | ... | ... |
impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/util/SessionListener.java
| ... | ... | @@ -24,9 +24,8 @@ public class SessionListener implements HttpSessionListener { |
| 24 | 24 | public void sessionCreated(final HttpSessionEvent sessionEvent) { |
| 25 | 25 | Beans.getBeanManager().fireEvent(new AfterSessionCreated() { |
| 26 | 26 | @Override |
| 27 | - public String getSessionId() { | |
| 28 | - HttpSession session = sessionEvent.getSession(); | |
| 29 | - return session!=null ? session.getId() : null; | |
| 27 | + public HttpSession getSession() { | |
| 28 | + return sessionEvent.getSession(); | |
| 30 | 29 | } |
| 31 | 30 | }); |
| 32 | 31 | } |
| ... | ... | @@ -35,9 +34,8 @@ public class SessionListener implements HttpSessionListener { |
| 35 | 34 | public void sessionDestroyed(final HttpSessionEvent sessionEvent) { |
| 36 | 35 | Beans.getBeanManager().fireEvent(new BeforeSessionDestroyed() { |
| 37 | 36 | @Override |
| 38 | - public String getSessionId() { | |
| 39 | - HttpSession session = sessionEvent.getSession(); | |
| 40 | - return session!=null ? session.getId() : null; | |
| 37 | + public HttpSession getSession() { | |
| 38 | + return sessionEvent.getSession(); | |
| 41 | 39 | } |
| 42 | 40 | }); |
| 43 | 41 | } | ... | ... |