1、配置spring session redis相关maven依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.sessiongroupId>
<artifactId>spring-session-data-redisartifactId>
dependency>
2、项目配置spring session存储类型为redis,并对redis配置
spring.session.store-type=redis
spring.redis.host=47.97.23.184
spring.redis.port=6379
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=30
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.timeout=10
3、启用 @EnableRedisHttpSession
(不配置RedisHttpSessionConfig,直接在启动类中添加此注解即可)
1)第一种,直接在启动类中启用 @EnableRedisHttpSession
@SpringBootApplication
@EnableRedisHttpSession
public class SpringSessionApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSessionApplication.class, args);
}
}
2)第二种,不修改启动类,增加一个RedisHttpSessionConfig配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfig {
/**
* @EnableRedisHttpSession的SessionMessageListener和启用必要的Redis KEYSPACE事件是自动完成的。
* 但是,在安全的Redis环境中,config命令被禁用。这意味着Spring Session无法为您配置Redis Keyspace事件。
* 要禁用自动配置,请添加ConfigureRedisAction.NO_OP为bean
* @return
*/
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
}
http://localhost:8080/session/test
127.0.0.1:6379> keys *
1) "spring:session:sessions:expires:01cc33eb-aceb-4109-98ad-651a0a9bd40d"
2) "spring:session:sessions:01cc33eb-aceb-4109-98ad-651a0a9bd40d"
3) "spring:session:expirations:1539163980000"
127.0.0.1:6379> object encoding spring:session:sessions:01cc33eb-aceb-4109-98ad-651a0a9bd40d
"hashtable"
表示session存储的是hash数据结构,故而直接存放各种key/value即可
1、从入口标签@EnableRedisHttpSession 进入查看源码,发现其import 导入了类 RedisHttpSessionConfiguration,接着点进去,重点在其父类 SpringHttpSessionConfiguration
public class SpringHttpSessionConfiguration implements ApplicationContextAware
2、在SpringHttpSessionConfiguration中SessionRepositoryFilter(会话过滤器)是Spring Session最核心的地方。其中最重要的方法doFilterInternal如下:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryFilter.SessionRepositoryRequestWrapper(request, response, this.servletContext);
SessionRepositoryFilter.SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryFilter.SessionRepositoryResponseWrapper(wrappedRequest, response);
try {
//将filter添加到FilterChain中
filterChain.doFilter(wrappedRequest, wrappedResponse);
} finally {
//保存session信息
wrappedRequest.commitSession();
}
}
SessionRepositoryFilter 实现了doFilterInternal,方法内部创建了SessionRepositoryRequestWrapper、SessionRepositoryResponseWrapper,将filter添加到FilterChain中,最后调用commitSession()保存session信息到redis
FilterChain:过滤器链作用,当一个filter收到请求的时候,调用chain.doFilter才可以访问下一个匹配的filter,若当前的filter是最后一 个filter,调用chain.doFilter才能访问目标资源。多个filter的执行顺序是由web.xml中filter-mapping的位置决定的.
Spring Session Redis 源码分析可参考 https://blog.csdn.net/u010648555/article/details/79491988,分析得很详细。
No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Description:
Parameter 1 of method sessionRepositoryFilterRegistration in org.springframework.boot.autoconfigure.session.SessionRepositoryFilterConfiguration required a bean of type ‘org.springframework.data.redis.connection.RedisConnectionFactory’ that could not be found.
- Bean method ‘redisConnectionFactory’ not loaded because @ConditionalOnClass did not find required classes ‘org.apache.commons.pool2.impl.GenericObjectPool’, ‘redis.clients.jedis.Jedis’
- Bean method ‘redisConnectionFactory’ not loaded because @ConditionalOnClass did not find required class ‘io.lettuce.core.RedisClient’
Action:
Consider revisiting the entries above or defining a bean of type ‘org.springframework.data.redis.connection.RedisConnectionFactory’ in your configuration.
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>2.9.0version>
dependency>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘enableRedisKeyspaceNotificationsInitializer’ defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Unable to configure Redis to keyspace notifications. See http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-sessiondestroyedevent
@EnableRedisHttpSession的SessionMessageListener和启用必要的Redis KEYSPACE事件是自动完成的。但是,在安全的Redis环境中,config命令被禁用。这意味着Spring Session无法为您配置Redis Keyspace事件。要禁用自动配置,请添加ConfigureRedisAction.NO_OP为bean。
在RedisHttpSessionConfig中添加代码:
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
Redis需要设置可远程访问
redis.conf中注释掉bind、并将 protected-mode yes 设置为 protected-mode no