The @PostConstruct and @PreDestroy annotation support on CustomScoped beans already seemed to be partially supported. Though I haven't looked into the JSF source code, I suspect the following two calls in WindowScopeManager to help out with the current support of this:
- facesContext.getApplication().publishEvent(facesContext, PostConstructCustomScopeEvent.class, context);
- facesContext.getApplication().publishEvent(facesContext, PreDestroyCustomScopeEvent.class, context);
These calls and the locations in the code where these calls are made seem to explain the 2 working scenarios:
- Whenever a window scoped bean is created the @PostConstruct on this window scoped bean gets invoked
- Whenever a window scoped bean is abandoned but the session hasn't expired yet, the @PreDestroy on this window scoped bean gets invoked
The one missing case seem to be the invocation of @PreDestroy upon session expiry for all remaining window scoped beans in the session. However, upon session expiry you're not guaranteed to have a FacesContext. Therefore the similar mechanism cannot be used. Instead, the SessionExpiredListener now invokes the newly created WindowScopeManager.disposeWindows(HttpSession) upon session expiry:
public void sessionDestroyed(HttpSessionEvent httpSessionEvent)
{
...
HttpSession session = httpSessionEvent.getSession();
WindowScopeManager.disposeWindows(session);
...
}
public static void disposeWindows(final HttpSession session) {
State state = (State)session.getAttribute(WindowScopeManager.class.getName());
Collection<ScopeMap> scopeMaps = state.windowScopedMaps.values();
for (final ScopeMap scopeMap : scopeMaps) {
Collection<Object> windowScopedBeans = scopeMap.values();
for (final Object windowScopedBean : windowScopedBeans)
{
callPreDestroy(windowScopedBean);
}
}
}
However, currently the @PreDestroy on an abandoned window scoped bean gets invoked twice: ICE-7055
The @PostConstruct and @PreDestroy annotation support on CustomScoped beans already seemed to be partially supported. Though I haven't looked into the JSF source code, I suspect the following two calls in WindowScopeManager to help out with the current support of this:
These calls and the locations in the code where these calls are made seem to explain the 2 working scenarios:
The one missing case seem to be the invocation of @PreDestroy upon session expiry for all remaining window scoped beans in the session. However, upon session expiry you're not guaranteed to have a FacesContext. Therefore the similar mechanism cannot be used. Instead, the SessionExpiredListener now invokes the newly created WindowScopeManager.disposeWindows(HttpSession) upon session expiry:
public void sessionDestroyed(HttpSessionEvent httpSessionEvent)
{ ... HttpSession session = httpSessionEvent.getSession(); WindowScopeManager.disposeWindows(session); ... }public static void disposeWindows(final HttpSession session) {
{ callPreDestroy(windowScopedBean); }State state = (State)session.getAttribute(WindowScopeManager.class.getName());
Collection<ScopeMap> scopeMaps = state.windowScopedMaps.values();
for (final ScopeMap scopeMap : scopeMaps) {
Collection<Object> windowScopedBeans = scopeMap.values();
for (final Object windowScopedBean : windowScopedBeans)
}
}
However, currently the @PreDestroy on an abandoned window scoped bean gets invoked twice:
ICE-7055