总体理解

  • 听起来如果是权限控制时使用ThreadLocal,并不是出于减少查询Redis数据库的目的,而是为了保证数据完整性,Thread线程独占某个资源避免高并发时出现数据异常和串号的情况。

Controller

  1. @RestController
  2. @RequestMapping("/threadLocal")
  3. public class ThreadLocalController {
  4. @RequestMapping("/test")
  5. @ResponseBody
  6. public Long test() {
  7. return RequestHolder.getId();
  8. }
  9. }

RequestHolder

  1. public class RequestHolder {
  2. private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();
  3. public static void add(long id) {
  4. requestHolder.set(id);
  5. }
  6. public static Long getId() {
  7. return requestHolder.get();
  8. }
  9. public static void remove() {
  10. requestHolder.remove();
  11. }
  12. }

HttpFilter

  1. @Slf4j
  2. public class HttpFilter implements Filter {
  3. @Override
  4. public void init(FilterConfig filterConfig) throws ServletException {
  5. }
  6. @Override
  7. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  8. HttpServletRequest request = (HttpServletRequest) servletRequest;
  9. log.info("do filter, {}, {}", Thread.currentThread().getId(), request.getServletPath());
  10. //在ThreadLocal中添加当前线程的id
  11. RequestHolder.add(Thread.currentThread().getId());
  12. filterChain.doFilter(servletRequest, servletResponse);
  13. }
  14. @Override
  15. public void destroy() {
  16. }
  17. }

HttpInterceptor

  • 真实使用的时候

    1. @Slf4j
    2. public class HttpInterceptor extends HandlerInterceptorAdapter {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    5. log.info("preHandle");
    6. return true;
    7. }
    8. @Override
    9. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    10. log.info("ThreadId:"+RequestHolder.getId());
    11. RequestHolder.remove();
    12. log.info("afterCompletion");
    13. return;
    14. }
    15. }

DemoApplication

  1. @SpringBootApplication(scanBasePackages = "Controller")
  2. public class DemoApplication extends WebMvcConfigurerAdapter {
  3. public static void main(String[] args)
  4. {
  5. SpringApplication.run(DemoApplication.class, args);
  6. }
  7. @Bean
  8. public FilterRegistrationBean httpFilter() {
  9. FilterRegistrationBean registrationBean = new FilterRegistrationBean();
  10. registrationBean.setFilter(new HttpFilter());
  11. registrationBean.addUrlPatterns("/threadLocal/*");
  12. return registrationBean;
  13. }
  14. @Override
  15. public void addInterceptors(InterceptorRegistry registry) {
  16. registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");
  17. }
  18. }