I've also posted this in the Spring forums, but figured I'd give folks here a shot at adding to their reputation:
For plain old servlet apps operating in a clustered environment (session replication/failover), it's good practice to "re-set" session attributes if they've been modified:
UserPreferences prefs = (UserPreferences)session.getAttribute("userPreferences");
prefs.setInstantEmail(true);
session.setAttribute("userPreferences", prefs);
This acts as a flag to the container that session state has changed and replication is required. Here's a reference to some WLS documentation on the subject.
An app I'm currently modifying uses Spring to support a POJO+Injection style of development and I'm开发者_开发知识库 not clear on how the above practice translates. Per the Spring docs, Scoped beans as dependencies, the app uses <aop:scoped-proxy/>
to inject a session-scoped dependency. However, without direct access to the session, how are changes to that dependency flagged to the container so that replication can occur? Is there something built into either the proxy or the web context to support it? If not, does anyone have examples of how they're handling it?
Thanks for any insight.
Clarification based on axtavt's answer:
One of the project's goals in following a POJO+Injection approach is to avoid direct dependencies on either Java EE or Spring classes. I can imagine that Spring might expose some hooks into retrieving beans from a context which could provide a place to at least track which session-scoped beans have been used. Another possibility might be declaring the set of methods on the session-scoped bean that, when invoked, could trigger a state change. Not being intimately familiar with Spring, I can only guess at what seems possible without knowing the technical details.
Follow-on question after looking at some Spring code:
Can anyone shed some light on the role that ServletRequestAttributes
might play? It looks like its getAttribute
method tracks which attributes have been retrieved and then its updateAccessedSessionAttributes
method attempts to "re-set" the attributes it believes have changed.
Where is no built-in support for this.
From looking at the code, you can do it manually as follows:
RequestAttributes a = RequestContextHolder.currentRequestAttributes();
String name = ScopedProxyUtils.getTargetBeanName("...your bean name...")
synchronized (a.getSessionMutex()) {
Object o = a.getAttribute(name, RequestAttributes.SCOPE_SESSION);
a.setAttribute(name, o, RequestAttributes.SCOPE_SESSION);
}
As it turns out, I was able to talk to someone from SpringSource support who verified that ServletRequestAttributes
is the entity in charge of doing the "re-set".
精彩评论