apply from: JAVA_GRADLEapply from: MAVEN_GRADLEapply plugin: 'spring-io'description = "Aggregator for Spring Session and Spring Data Redis"dependencies { compile project(':spring-session'), "org.springframework.data:spring-data-redis:$springDataRedisVersion", "redis.clients:jedis:$jedisVersion", "org.apache.commons:commons-pool2:$commonsPoolVersion" springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties"}
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.0.1.RELEASE</version></dependency>
import org.springframework.context.annotation.Bean;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 7200)public class RedisHttpSessionConfig { @Bean public RedisConnectionFactory connectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); connectionFactory.setPort(6379); connectionFactory.setHostName("10.18.15.190"); return connectionFactory; }}
//该类采用Java Configuration,来代替web.xml public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{Config1.class, Config2.class, RedisHttpSessionConfig.class}; } //......}
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;public class SpringSessionInitializer extends AbstractHttpSessionApplicationInitializer {}
package org.springframework.session.data.redis.config.annotation.web.http;@Configuration@EnableSchedulingpublic class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoaderAware { //...... @Bean public RedisTemplate<String,ExpiringSession> sessionRedisTemplate(RedisConnectionFactory connectionFactory) { //...... return template; } @Bean public RedisOperationsSessionRepository sessionRepository(RedisTemplate<String, ExpiringSession> sessionRedisTemplate) { //...... return sessionRepository; } @Bean public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository, ServletContext servletContext) { //...... return sessionRepositoryFilter; } //......}
package org.springframework.session.web.context;/** * Registers the {@link DelegatingFilterProxy} to use the * springSessionRepositoryFilter before any other registered {@link Filter}. * * ...... */@Order(100)public abstract class AbstractHttpSessionApplicationInitializer implements WebApplicationInitializer { private static final String SERVLET_CONTEXT_PREFIX = "org.springframework.web.servlet.FrameworkServlet.CONTEXT."; public static final String DEFAULT_FILTER_NAME = "springSessionRepositoryFilter"; //...... public void onStartup(ServletContext servletContext) throws ServletException { beforeSessionRepositoryFilter(servletContext); if(configurationClasses != null) { AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext(); rootAppContext.register(configurationClasses); servletContext.addListener(new ContextLoaderListener(rootAppContext)); } insertSessionRepositoryFilter(servletContext);//注册一个SessionRepositoryFilter afterSessionRepositoryFilter(servletContext); } /** * Registers the springSessionRepositoryFilter * @param servletContext the {@link ServletContext} */ private void insertSessionRepositoryFilter(ServletContext servletContext) { String filterName = DEFAULT_FILTER_NAME;//默认名字是springSessionRepositoryFilter DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(filterName);//该Filter代理会在初始化时从Spring容器中查找springSessionRepositoryFilter,之后实际会使用SessionRepositoryFilter进行doFilter操作 String contextAttribute = getWebApplicationContextAttribute(); if(contextAttribute != null) { springSessionRepositoryFilter.setContextAttribute(contextAttribute); } registerFilter(servletContext, true, filterName, springSessionRepositoryFilter); } //......}
@Order(SessionRepositoryFilter.DEFAULT_ORDER)public class SessionRepositoryFilter implements Filter { public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest httpRequest = (HttpServletRequest) request; SessionRepositoryRequestWrapper customRequest = new SessionRepositoryRequestWrapper(httpRequest); chain.doFilter(customRequest, response, chain); } // ...}
public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper { public SessionRepositoryRequestWrapper(HttpServletRequest original) { super(original); } public HttpSession getSession() { return getSession(true); } public HttpSession getSession(boolean createNew) { // create an HttpSession implementation from Spring Session } // ... other methods delegate to the original HttpServletRequest ...}
package org.springframework.web;@HandlesTypes(WebApplicationInitializer.class)public class SpringServletContainerInitializer implements ServletContainerInitializer { /** * Delegate the {@code ServletContext} to any {@link WebApplicationInitializer} * implementations present on the application classpath. * * <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)}, * Servlet 3.0+ containers will automatically scan the classpath for implementations * of Spring's {@code WebApplicationInitializer} interface and provide the set of all * such types to the {@code webAppInitializerClasses} parameter of this method. * * <p>If no {@code WebApplicationInitializer} implementations are found on the * classpath, this method is effectively a no-op. An INFO-level log message will be * issued notifying the user that the {@code ServletContainerInitializer} has indeed * been invoked but that no {@code WebApplicationInitializer} implementations were * found. * * <p>Assuming that one or more {@code WebApplicationInitializer} types are detected, * they will be instantiated (and <em>sorted</em> if the @{@link * org.springframework.core.annotation.Order @Order} annotation is present or * the {@link org.springframework.core.Ordered Ordered} interface has been * implemented). Then the {@link WebApplicationInitializer#onStartup(ServletContext)} * method will be invoked on each instance, delegating the {@code ServletContext} such * that each instance may register and configure servlets such as Spring's * {@code DispatcherServlet}, listeners such as Spring's {@code ContextLoaderListener}, * or any other Servlet API componentry such as filters. * * @param webAppInitializerClasses all implementations of * {@link WebApplicationInitializer} found on the application classpath * @param servletContext the servlet context to be initialized * @see WebApplicationInitializer#onStartup(ServletContext) * @see AnnotationAwareOrderComparator */ @Override public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { //...... }}
127.0.0.1:6379> keys *1) "spring:session:expirations:1431577740000"2) "spring:session:sessions:e2cef3ae-c8ea-4346-ba6b-9b3b26eee578"127.0.0.1:6379> type spring:session:sessions:e2cef3ae-c8ea-4346-ba6b-9b3b26eee578hash127.0.0.1:6379> type spring:session:expirations:1431577740000set
127.0.0.1:6379> keys *1) "spring:session:expirations:1431527520000"2) "spring:session:sessions:59f3987c-d1e4-44b3-a83a-32079942888b"3) "spring:session:sessions:11a69da6-138b-42bc-9916-60ae78aa55aa"4) "spring:session:sessions:0a51e2c2-4a3b-4986-a754-d886d8a5d42d"5) "spring:session:expirations:1431527460000"127.0.0.1:6379> hkeys spring:session:sessions:59f3987c-d1e4-44b3-a83a-32079942888b1) "maxInactiveInterval"2) "creationTime"3) "lastAccessedTime"4) "sessionAttr:attr1"127.0.0.1:6379> hget spring:session:sessions:59f3987c-d1e4-44b3-a83a-32079942888b sessionAttr:attr1"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x03"127.0.0.1:6379> hget spring:session:sessions:59f3987c-d1e4-44b3-a83a-32079942888b creationTime"\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01MM\x94(\xec"
联系客服