реализация сеанса весенней сессии не получает расширенный прокси-компонент CGLIB - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь перенести spring-session в существующее веб-приложение, которое использует bean-объекты сессионной области. Это приложение работает на Wildfly 10.1.0.Final

Когда я запускаю приложение, использующее внутреннее управление сессиями wildfly, все работает нормально. Попытка добавить пользовательскую реализацию Spring-Session приводит к потере информации о сессионном компоненте. Когда я отлаживаю приложение, происходит вызов 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 имеет bean-объект области действия UserSessionData, я получаю необработанный экземпляр прокси-класса, а не декорированный экземпляр, который имеет значения сеанса. Я смог убедиться в этом, отладив приведенный ниже SesssionImpl в методе #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);
        }
    }
}

Я чувствую, что мне не хватает ни конфигурации, ни чего-то другого, потому что нативный WildFly SessionImpl имеет правильный расширенный объект для сериализации, когда я удаляю springSessionRepositoryFilter и позволяю контейнеру обрабатывать объект сеанса. Кроме того, у контроллеров Spring есть правильный расширенный объект. Это просто MySession, который, кажется, не получает это. Есть мысли?

EDIT: Похоже, основная проблема заключается в том, что мой 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. Когда я использую @Autowired в контроллерах MVC, я получаю правильный.

Версии библиотеки:

  • Весна: 3.2.14
  • Весенняя сессия: 1.3.2
  • WildFly 10.1.0. Финал
...