ThreadLocal 同一线程数据共享
同一线程指:请求到连接器到controoler到service执行时同一个线程
ThreadLocal 调用setget方法可以实现统一线程的数据共享
public static ThreadLocal<MemberResponseVo> loginUser = new ThreadLocal<>();
loginUser.set(Userr);
loginUser.get();
openFeign
1.feign远程调用丢失请求头问题
原因:feign在请求前会构造请求,执行拦截器的进一步构造进行新请求增强,构造的对象没有请求头
解决:加上feign远程调用的拦截器
@Configuration
public class GuliFeignConfig {
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor() {
RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
//1、使用RequestContextHolder拿到刚进来的请求数据
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
//老请求
HttpServletRequest request = requestAttributes.getRequest();
if (request != null) {
//2、同步请求头的数据(主要是cookie)
//把老请求的cookie值放到新请求上来,进行一个同步
String cookie = request.getHeader("Cookie");
template.header("Cookie", cookie);
}
}
}
};
return requestInterceptor;
}
}
2.feign丢失上下文问题
原因: 开启异步编排导致丢失上下文----因为用的ThreadLocal同一线程数据共享,所以异步编排就会导致线程多个,子线程丢失上下文从而获取不到主线程的ThreadLocal共享数据
解决:
1. 在主线程中获取上下文
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
2.在子线程中设置主线程的上下文
RequestContextHolder.setRequestAttributes(requestAttributes);
session共享
使用session-redis 储存session
1.pom 依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.主启动类加注解
@EnableRedisHttpSession //整合redis作为session的存储
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallAuthServerApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallAuthServerApplication.class, args);
}
}
3. 配置cookie和域
@Configuration
public class GulimallSessionConfig {
@Bean // redis的json序列化
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
@Bean // cookie
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("GULISESSIONID"); // cookie的键
serializer.setDomainName("gulimall.com"); // 扩大session作用域,也就是cookie的有效域
return serializer;
}
}