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,7 +36,6 @@ | ||
36 | */ | 36 | */ |
37 | package br.gov.frameworkdemoiselle.internal.context; | 37 | package br.gov.frameworkdemoiselle.internal.context; |
38 | 38 | ||
39 | -import java.util.concurrent.ConcurrentHashMap; | ||
40 | import java.util.concurrent.atomic.AtomicLong; | 39 | import java.util.concurrent.atomic.AtomicLong; |
41 | 40 | ||
42 | import javax.enterprise.context.ApplicationScoped; | 41 | import javax.enterprise.context.ApplicationScoped; |
@@ -70,23 +69,24 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | @@ -70,23 +69,24 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | ||
70 | 69 | ||
71 | private final AtomicLong atomicLong = new AtomicLong(); | 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 | private static final String FACES_KEY = FacesViewContextImpl.class.getCanonicalName(); | 74 | private static final String FACES_KEY = FacesViewContextImpl.class.getCanonicalName(); |
76 | - | 75 | + private static final String VIEW_STORE_KEY = FacesViewBeanStore.class.getCanonicalName(); |
76 | + | ||
77 | public FacesViewContextImpl() { | 77 | public FacesViewContextImpl() { |
78 | super(ViewScoped.class); | 78 | super(ViewScoped.class); |
79 | } | 79 | } |
80 | 80 | ||
81 | @Override | 81 | @Override |
82 | protected boolean isStoreInitialized() { | 82 | protected boolean isStoreInitialized() { |
83 | - return FacesContext.getCurrentInstance()!=null && getSessionId()!=null; | 83 | + return FacesContext.getCurrentInstance()!=null && getSession()!=null; |
84 | } | 84 | } |
85 | 85 | ||
86 | @Override | 86 | @Override |
87 | protected BeanStore getStore() { | 87 | protected BeanStore getStore() { |
88 | - String sessionId = getSessionId(); | ||
89 | - if (sessionId == null){ | 88 | + HttpSession session = getSession(); |
89 | + if (session == null){ | ||
90 | return null; | 90 | return null; |
91 | } | 91 | } |
92 | 92 | ||
@@ -108,16 +108,16 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | @@ -108,16 +108,16 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | ||
108 | } | 108 | } |
109 | } | 109 | } |
110 | } | 110 | } |
111 | - | 111 | + |
112 | //A mesma técnica de bloqueio de thread acima é usada aqui para | 112 | //A mesma técnica de bloqueio de thread acima é usada aqui para |
113 | //criar um SessionBeanStore caso o mesmo ainda não exista. | 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 | if (currentStore==null){ | 115 | if (currentStore==null){ |
116 | synchronized (this) { | 116 | synchronized (this) { |
117 | - currentStore = (FacesViewBeanStore) sessionBeanStore.get(sessionId); | 117 | + currentStore = (FacesViewBeanStore) session.getAttribute(VIEW_STORE_KEY); |
118 | if (currentStore==null){ | 118 | if (currentStore==null){ |
119 | currentStore = new FacesViewBeanStore(); | 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,22 +129,18 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | ||
129 | * Called before the session is invalidated for that user. | 129 | * Called before the session is invalidated for that user. |
130 | * Destroys all view scoped beans stored on that session. | 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 | if (store!=null){ | 135 | if (store!=null){ |
136 | + session.removeAttribute(VIEW_STORE_KEY); | ||
136 | store.clear(this); | 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,11 +158,11 @@ public class FacesViewContextImpl extends AbstractCustomContext implements ViewC | ||
162 | * Destroys all view scoped beans stored on that session. | 158 | * Destroys all view scoped beans stored on that session. |
163 | */ | 159 | */ |
164 | protected void clearInvalidatedSession(@Observes BeforeSessionDestroyed event){ | 160 | protected void clearInvalidatedSession(@Observes BeforeSessionDestroyed event){ |
165 | - String sessionId = event.getSessionId(); | 161 | + HttpSession session = event.getSession(); |
166 | try{ | 162 | try{ |
167 | Context context = Beans.getBeanManager().getContext(ViewScoped.class); | 163 | Context context = Beans.getBeanManager().getContext(ViewScoped.class); |
168 | if ( FacesViewContextImpl.class.isInstance(context) ){ | 164 | if ( FacesViewContextImpl.class.isInstance(context) ){ |
169 | - ((FacesViewContextImpl)context).clearInvalidatedSession(sessionId); | 165 | + ((FacesViewContextImpl)context).clearInvalidatedSession(session); |
170 | } | 166 | } |
171 | } | 167 | } |
172 | catch(ContextNotActiveException ce){ | 168 | catch(ContextNotActiveException ce){ |
impl/extension/servlet/src/main/java/br/gov/frameworkdemoiselle/lifecycle/AfterSessionCreated.java
1 | package br.gov.frameworkdemoiselle.lifecycle; | 1 | package br.gov.frameworkdemoiselle.lifecycle; |
2 | 2 | ||
3 | +import javax.servlet.http.HttpSession; | ||
4 | + | ||
3 | /** | 5 | /** |
4 | * This interface represents an event fired after a new HTTP session is created. | 6 | * This interface represents an event fired after a new HTTP session is created. |
5 | * | 7 | * |
@@ -10,8 +12,8 @@ public interface AfterSessionCreated { | @@ -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 | package br.gov.frameworkdemoiselle.lifecycle; | 1 | package br.gov.frameworkdemoiselle.lifecycle; |
2 | 2 | ||
3 | +import javax.servlet.http.HttpSession; | ||
4 | + | ||
3 | /** | 5 | /** |
4 | * This interface represents an event fired before an HTTP session is destroyed. | 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,9 +11,14 @@ package br.gov.frameworkdemoiselle.lifecycle; | ||
9 | public interface BeforeSessionDestroyed { | 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 | \ No newline at end of file | 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,9 +24,8 @@ public class SessionListener implements HttpSessionListener { | ||
24 | public void sessionCreated(final HttpSessionEvent sessionEvent) { | 24 | public void sessionCreated(final HttpSessionEvent sessionEvent) { |
25 | Beans.getBeanManager().fireEvent(new AfterSessionCreated() { | 25 | Beans.getBeanManager().fireEvent(new AfterSessionCreated() { |
26 | @Override | 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,9 +34,8 @@ public class SessionListener implements HttpSessionListener { | ||
35 | public void sessionDestroyed(final HttpSessionEvent sessionEvent) { | 34 | public void sessionDestroyed(final HttpSessionEvent sessionEvent) { |
36 | Beans.getBeanManager().fireEvent(new BeforeSessionDestroyed() { | 35 | Beans.getBeanManager().fireEvent(new BeforeSessionDestroyed() { |
37 | @Override | 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 | } |