Spring-Session会话实现未获取CGLIB增强代理Bean问题求助
嘿,你碰到的这个问题我之前在帮团队排查Wildfly集成Spring-Session时也遇到过,核心就是会话作用域Bean没被Spring正确生成CGLIB代理,导致切换到Spring-Session后,会话上下文里的Bean状态完全没法正常维护。下面我给你拆解下问题根源和对应的解决步骤:
Wildfly自带的会话管理是和它的容器生命周期深度绑定的,而Spring-Session是通过替换Servlet容器的HttpSession实现来接管会话逻辑。当你使用会话作用域Bean时,Spring默认会用CGLIB生成代理类包装原始Bean——这样才能在会话上下文切换时,正确追踪和维护Bean的状态。但现在scopedTarget.userSessionData是原始的UserSessionData类而非代理类,说明Spring的代理机制压根没生效,大概率是这几个原因:
- Wildfly的原生会话作用域和Spring的
session作用域底层实现冲突,导致Spring没法生成代理; - 你的会话Bean配置里没显式指定代理模式,Spring默认用了JDK动态代理(但你的Bean没实现接口,所以代理失败);
- Wildfly的模块化类加载器隔离了Spring的CGLIB类,导致生成的代理类没法被正确加载。
1. 给会话Bean强制指定CGLIB代理模式
在你的UserSessionData类上,显式配置@Scope的代理模式为TARGET_CLASS,让Spring强制生成CGLIB代理:
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) @Component public class UserSessionData { // 你的Bean属性和方法 }
这里proxyMode = ScopedProxyMode.TARGET_CLASS是关键——它会绕过JDK动态代理的限制,直接针对类生成CGLIB代理,确保会话Bean被正确包装。
2. 让Wildfly放弃接管HttpSession
在web.xml里添加配置,完全把会话管理交给Spring-Session:
<web-app> <!-- 其他已有配置 --> <context-param> <param-name>org.springframework.web.context.request.DispatcherServlet.ENABLE_SPRING_SESSION</param-name> <param-value>true</param-value> </context-param> <session-config> <tracking-mode>COOKIE</tracking-mode> <!-- 会话超时时间和Spring-Session保持一致 --> <session-timeout>30</session-timeout> </session-config> </web-app>
如果是Spring Boot项目,还可以在application.properties里加这两行:
server.servlet.session.persistent=false spring.session.store-type=redis # 换成你实际用的存储类型,比如jdbc
3. 调整Wildfly的类加载器配置
Wildfly的模块化类加载可能会干扰CGLIB代理类的加载,你可以在项目根目录下创建jboss-deployment-structure.xml,让Spring相关类优先从应用的WEB-INF/lib加载:
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.springframework.spring" export="true" /> </dependencies> <exclude-subsystems> <!-- 排除Wildfly的Undertow会话子系统,避免冲突 --> <subsystem name="undertow" /> </exclude-subsystems> </deployment> </jboss-deployment-structure>
4. 确保Spring-Session过滤器优先级最高
Spring-Session的过滤器必须在所有其他过滤器之前执行,这样才能完全接管HttpSession。在web.xml里配置:
<filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
配置完重启Wildfly,调试时再看scopedTarget.userSessionData的类型——如果是UserSessionData$$EnhancerBySpringCGLIB$$xxxx这种带CGLIB后缀的代理类,说明配置生效了,此时会话Bean的状态应该就能正常被Spring-Session维护了。
内容的提问来源于stack exchange,提问作者Ryan S

