Java ThreadLocal-使用spring引导作为REST API的上下文信息
我有一些Java ThreadLocal-使用spring引导作为REST API的上下文信息,java,spring-boot,spring-security,thread-safety,thread-local,Java,Spring Boot,Spring Security,Thread Safety,Thread Local,我有一些springboot应用程序(它公开了restapi)。提到的RESTAPI 由spring security保护。一切都很好,但现在我需要设置上下文 服务请求。设置上下文是关于根据用户上下文在中选择数据源。关键是RoutingDataSource需要使用此上下文。(由于其他原因,此上下文必须在验证请求后直接设置,我还有其他线程使用RoutingDataSource,但没有被请求调用(没有用户上下文)) 我可以做这些事情,但我怀疑上下文的线程安全性和清除它。我试图在文档中找到答案,但没能
springboot
应用程序(它公开了restapi)。提到的RESTAPI
由spring security
保护。一切都很好,但现在我需要设置上下文
服务请求。设置上下文是关于根据用户上下文在中选择数据源。关键是RoutingDataSource需要使用此上下文。(由于其他原因,此上下文必须在验证请求后直接设置,我还有其他线程使用RoutingDataSource,但没有被请求调用(没有用户上下文))
我可以做这些事情,但我怀疑上下文的线程安全性和清除它。我试图在文档中找到答案,但没能找到
public class CustomContextHolder {
private static final ThreadLocal<DatabaseType> contextHolder =
new ThreadLocal<DatabaseType>();
public static void setContext(DatabaseType databaseType) {
contextHolder.set(databaseType);
}
public static CustomerType getContext() {
return (CustomerType) contextHolder.get();
}
public static void clearContext() {
contextHolder.remove();
}
}
我能做到。但是,由于spring-boot
是多线程的,并且我使用ThreadLocal
作为保持上下文,因此我担心此配置的线程安全性
当我设置这个上下文时?
在筛选器中,仅在成功授权请求后。因此,问题是:
clearContext()
关于第二个问题:在设置线程本地的过滤器中清除线程本地
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
boolean contextSetViaThreadLocal = false;
if (authentication != null && authentication.isAuthenticated()) {
contextSetViaThreadLocal = true;
// here we set context
}
// immediately after the conditional context store
try {
filterChain.doFilter(request, response);
} finally {
if (contextSetViaThreadLocal) {
// clear the context
}
}
如果您想使用ThreadLocal,您需要澄清并最小化应用程序中的线程生命周期。请求完成后,您应该立即清除上下文
try {
filterChain.doFilter(request, response);
}
finally {
// remove context here
}
它是单线程的,除非您有意启动子线程。 在这种情况下,请使用存储信息。还有另一种与weblogic部署相关的方法,线程本地方法可能是一种可行的解决方案。
try {
filterChain.doFilter(request, response);
}
finally {
// remove context here
}