我试图将spring-session放入使用会话范围bean的现有Web应用程序中。此应用程序在Wildfly 10.1.0.Final
上运行当我运行应用程序使用wildfly的内部会话管理时,一切正常。尝试放入Spring-Session的自定义实现会丢失会话bean信息。当我调试应用程序时,会调用scopedTarget.userSessionData
,但它是基础类UserSessionData
,而不是具有实际数据的UserSessionData$$EnhancedBySpringCGLIB$$1234
。
配置-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="userSessionData" scope="session" class="UserSessionData">
<aop:scoped-proxy/>
</bean>
<context:annotation-config />
<bean class="my.MyHttpSessionConfiguration" />
</beans>
此配置使用springSessionRepositoryFilter
正确创建并注册MyHttpSessionConfiguration
。但问题是,当MySession对象具有UserSessionData
的会话范围bean时,我得到原始代理类实例,而不是具有会话值的装饰实例。我能够通过在#setAttribute方法
class UserSessionData {
private String _myValue;
public void setMyValue(String value) {
_myValue = value;
}
public String getMyValue() {
return _myValue;
}
}
final class MySession implements ExpiringSession {
private final MapSession _delegate;
private final Map<String, Object> _delta = new HashMap<>();
private boolean _isNew;
MySession() {
this(new MapSession());
_isNew = true;
flushImmediateIfNecessary();
}
MySession(MapSession session) {
if (session == null) {
throw new IllegalArgumentException("MapSession cannot be null");
}
_isNew = false;
_delegate = session;
}
public boolean isNew() {
return _isNew;
}
@Override
public String getId() {
return _delegate.getId();
}
@Override
public long getCreationTime() {
return _delegate.getCreationTime();
}
@Override
public long getLastAccessedTime() {
return _delegate.getLastAccessedTime();
}
@Override
public void setLastAccessedTime(long lastAccessedTime) {
_delegate.setLastAccessedTime(lastAccessedTime);
flushImmediateIfNecessary();
}
@Override
public void setMaxInactiveIntervalInSeconds(int interval) {
_delegate.setMaxInactiveIntervalInSeconds(interval);
flushImmediateIfNecessary();
}
@Override
public int getMaxInactiveIntervalInSeconds() {
return _delegate.getMaxInactiveIntervalInSeconds();
}
@Override
public boolean isExpired() {
return _delegate.isExpired();
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAttribute(String attributeName) {
return (T) _delegate.getAttribute(attributeName);
}
@Override
public Set<String> getAttributeNames() {
return _delegate.getAttributeNames();
}
@Override
public void setAttribute(String attributeName, Object attributeValue) {
_delegate.setAttribute(attributeName, attributeValue);
putAndFlush(attributeName, attributeValue);
}
@Override
public void removeAttribute(String attributeName) {
_delegate.removeAttribute(attributeName);
putAndFlush(attributeName, null);
}
Map<String, Object> getDelta() {
return _delta;
}
private void putAndFlush(String attr, Object value) {
_delta.put(attr, value);
flushImmediateIfNecessary();
}
private void flushImmediateIfNecessary() {
if (MySessionRepository.this._flushMode == MyFlushMode.IMMEDIATE) {
MySessionRepository.this.save(this);
}
}
}
我觉得我缺少配置或其他东西,因为当我删除springSessionRepositoryFilter并让容器处理会话对象时,本机WildFly SessionImpl具有正确的序列化增强对象。此外,Spring Controllers具有正确的增强对象。它只是MySession
似乎没有得到它。有什么想法吗?
编辑:
看起来核心问题是我的spring-security在设置成员时使用了不同版本的代理类,所以我没有在MySession
对象中获取它们。附件是Spring-Security的配置
public class WebSessionInitializer extends AbstractHttpSessionInitializer {
}
@Configuration
@EnableSpringHttpSession
public class MySessionConfiguration {
@Bean
public SessionRepository sessionRepository() {
return new MySessionRepository();
}
}
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="imb"
version="2.5">
<distributable />
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/configuration-spring.xml
</param-value>
</context-param>
我的实现正确添加了SpringSession过滤器。看来根本问题是当我进入spring-security时,它在UserSessionData
的不同实例上设置值而不是MySession
对象中的值。当我在MVC控制器中使用@Autowired
时,我得到了正确的。{/ p>
图书馆版本: