spring-session会话实现没有获得CGLIB增强代理Bean

时间:2018-05-08 22:21:05

标签: spring spring-aop spring-session cglib

我试图将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方法

上调试下面的SesssionImpl来验证这一点
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>

图书馆版本:

  • 春天:3.2.14
  • 春季会议:1.3.2
  • WildFly 10.1.0.Final

0 个答案:

没有答案