Spring Session在不改變原有使用方式的前提下可以管理session。
從註解@EnableSpringHttpSession入手:
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({ java.lang.annotation.ElementType.TYPE })
@Documented
@Import(SpringHttpSessionConfiguration.class)
@Configuration
public @interface EnableSpringHttpSession {
}
發現導入了配置類
SpringHttpSessionConfiguration
@Configuration
public class SpringHttpSessionConfiguration {
private CookieHttpSessionStrategy defaultHttpSessionStrategy = new CookieHttpSessionStrategy();
private HttpSessionStrategy httpSessionStrategy = this.defaultHttpSessionStrategy;
private List<HttpSessionListener> httpSessionListeners = new ArrayList<HttpSessionListener>();
private ServletContext servletContext;
@Bean
public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAdapter() {
return new SessionEventHttpSessionListenerAdapter(this.httpSessionListeners);
}
@Bean
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(
SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(
sessionRepository);
sessionRepositoryFilter.setServletContext(this.servletContext);
if (this.httpSessionStrategy instanceof MultiHttpSessionStrategy) {
sessionRepositoryFilter.setHttpSessionStrategy(
(MultiHttpSessionStrategy) this.httpSessionStrategy);
}
else {
sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);
}
return sessionRepositoryFilter;
}
@Autowired(required = false)
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Autowired(required = false)
public void setCookieSerializer(CookieSerializer cookieSerializer) {
this.defaultHttpSessionStrategy.setCookieSerializer(cookieSerializer);
}
@Autowired(required = false)
public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {
this.httpSessionStrategy = httpSessionStrategy;
}
@Autowired(required = false)
public void setHttpSessionListeners(List<HttpSessionListener> listeners) {
this.httpSessionListeners = listeners;
}
}
最底下有四個可以配置的Spring Session方式。看名字可以看出他們的作用。
這個配置往Spring容器中配置兩個bean。
SessionEventHttpSessionListenerAdapter session事件的監聽器適配器
SessionRepositoryFilter session 持久化的過濾器,這是Spring Session的核心。
SessionRepositoryFilter 可以支持兩種策略,
CookieHttpSessionStrategy是基於Cookie的默認實現。
MultiHttpSessionStrategy可以支持多個用戶在一個瀏覽器上。
SessionRepositoryFilter 過濾核心代碼
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
request, response, this.servletContext);
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
wrappedRequest, response);
HttpServletRequest strategyRequest = this.httpSessionStrategy
.wrapRequest(wrappedRequest, wrappedResponse);
HttpServletResponse strategyResponse = this.httpSessionStrategy
.wrapResponse(wrappedRequest, wrappedResponse);
try {
filterChain.doFilter(strategyRequest, strategyResponse);
}
finally {
wrappedRequest.commitSession();
}
HttpServletRequest strategyRequest = this.httpSessionStrategy
.wrapRequest(wrappedRequest, wrappedResponse);
HttpServletResponse strategyResponse = this.httpSessionStrategy
.wrapResponse(wrappedRequest, wrappedResponse);
}
SessionRepositoryRequestWrapper及
SessionRepositoryResponseWrapper是將
HttpServletRequest、HttpServletResponse包裝成的可以提供session持久化功能的類。
HttpServletRequest strategyRequest = this.httpSessionStrategy
.wrapRequest(wrappedRequest, wrappedResponse);
HttpServletResponse strategyResponse = this.httpSessionStrategy
.wrapResponse(wrappedRequest, wrappedResponse);
利用多態完成request及response的實現轉換。