Insight spring-session 配置(整合方式)

炸雞店老闆發表於2017-07-26

spring-session 專案實現了redis、jdbc、gemfire 版本的分散式httpsession。

整合方式分為註解、xml配置。

原理就是配置filter,代理原有的httpsession的生成、獲取、銷燬的實現

servlet、Spring整合方式-
org.springframework.web.context.support.WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext)
Filter實現類 org.springframework.web.filter.DelegatingFilterProxySpring-Session實現類  springSessionRepositoryFilter

那麼,這個filter是如何工作的?

從DelegatingFilterProxy入口,WebApplicationContext.getBean() 的方式獲取到我們需要的x-httpsession實現。

/**
 * 此處的 delegateToUse就是分散式httpsession的bean
 * doFilter過程中進行初始化check    (漂亮的程式碼隨處可見啊)
 * 然後將分散式httpsession加入請求的filterChain, 達到httpsession代理的目的
 **/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
    // Lazily initialize the delegate if necessary.
    Filter delegateToUse = this.delegate;
    if (delegateToUse == null) {
        synchronized (this.delegateMonitor) {
            if (this.delegate == null) {
                WebApplicationContext wac = findWebApplicationContext();
                if (wac == null) {
                    throw new IllegalStateException("No WebApplicationContext found: " + "no ContextLoaderListener or DispatcherServlet registered?");
                }
                this.delegate = initDelegate(wac);
            }
            delegateToUse = this.delegate;
        }
    }
    // Let the delegate perform the actual doFilter operation.
    invokeDelegate(delegateToUse, request, response, filterChain);
}


然後,需要的bean("springSessionRepositoryFilter") 是何時構造的?

看另外一部分配置,註解@EnableSpringHttpSession 或者xml宣告(SpringHttpSessionConfiguration)。

a. SessionRepositoryFilter 由SpringHttpSessionConfiguration 構造,意味著我們啟用spring-session。

b. httpSession的實現方式(Mongo、Jdbc、Redis...)基於此處SessionRepositoryFilter的構造入參,即sessionRepository

c. 配置spring容器中使用哪種SessionRepository,同樣,通過兩種方式: xml宣告(RedisHttpSessionConfiguration) 或者 @EnableRedisHttpSession、@EnableJdbcHttpSession...

/**
 * web.xml 配置的httpsession bean 來自此處
 * 構造spring-session filter 需要真正的儲存物件 redis/jdbc/gemfire
 **/
@Bean
public  SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository sessionRepository) {
    SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(sessionRepository);
    sessionRepositoryFilter.setServletContext(this.servletContext);
    sessionRepositoryFilter.setHttpSessionStrategy(this.httpSessionStrategy);
    return sessionRepositoryFilter;
}

備註:

1、java web獲取spring bean 的方案可以直接配置DelegatingFilterProxy即可。靈活使用spring 的另外一種解決思路。

2、如上xml宣告方式啟用spring-session,只需要配置RedisHttpSessionConfiguration即可,該類繼承自SpringHttpSessionConfiguration。

3、目前支援的分散式httpsession 包括:

JdbcHttpSessionConfiguration ,

RedisHttpSessionConfiguration , 

HazelcastHttpSessionConfiguration ,

GemFireHttpSessionConfiguration ,

MongoHttpSessionConfiguration


相關文章