软件编程
位置:首页>> 软件编程>> java编程>> Java自定义过滤器和 * 实现ThreadLocal线程封闭

Java自定义过滤器和 * 实现ThreadLocal线程封闭

作者:共饮一杯无  发布时间:2023-09-19 04:29:04 

标签:Java,ThreadLocal,线程封闭

线程封闭

线程封闭一般通过以下三个方法:

  • Ad-hoc线程封闭:程序控制实现,最糟糕,忽略

  • 堆栈封闭:局部变量,无并发问题

  • ThreadLocal线程封闭:特别好的封闭方法

方法2是最常用的,变量定义在接口内,本文主要讲解方法三,SpringBoot项目通过自定义过滤器和 * 实现ThreadLocal线程封闭。实现Filter接口自定义过滤器和继承HandlerInterceptorAdapter自定义 * 。

ThreadLocal线程封闭实现步骤

封装ThredLocal的方法

/**
* <p>自定义RequestHolder</p></p>
*
* @Author zjq
* @Date 2021/12
*/
public class RequestHolder {

private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();

public static void set(Long id) {
       requestHolder.set(id);
   }

public static Long get() {
       return requestHolder.get();
   }

public static void remove() {
       requestHolder.remove();
   }

}

自定义过滤器

自定义定义 * 继承Filter接口,实现ThredLocal.add()方法

/**
* <p>自定义过滤器</p>
*
* @Author zjq
* @Date 2021/12/7
*/
@Slf4j
public class HttpFilter implements Filter {

/**
    * 为Filter初始化 提供支持
    *
    * @param filterConfig
    * @throws ServletException
    */
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {

}

/**
    * 拦截到要执行的请求时,doFilter就会执行。这里我们可以写对请求和响应的预处理。
    * FilterChain把请求和响应传递给下一个 Filter处理
    *
    * @param servletRequest
    * @param servletResponse
    * @param filterChain
    * @throws IOException
    * @throws ServletException
    */
   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       //把普通servlet强转成httpServlet
       HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
       Long threadId = Thread.currentThread().getId();
       log.info("do filter,threadId:{} servletPath:{}", threadId, httpServletRequest.getServletPath());
       //把当前线程id放入requestHolder
       RequestHolder.set(threadId);
       //放行
       filterChain.doFilter(httpServletRequest, servletResponse);
   }

/**
    * Filter 实例销毁前的准备工作
    */
   @Override
   public void destroy() {

}
}

自定义 *

自定义 * 在线程使用完毕后移除ThredLocal中内容,避免内存溢出

/**
* <p>自定义 * </p>
*
* @Author zjq
* @Date 2021/12/7
*/
@Slf4j
public class HttpInterceptor extends HandlerInterceptorAdapter {

/**
    * 拦截处理程序的执行。在 HandlerMapping 确定合适的处理程序对象之后,在 HandlerAdapter 调用处理程序之前调用。
    * @param request
    * @param response
    * @param handler
    * @return
    * @throws Exception
    */
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       log.info("preHandle执行。。。");
       return true;
   }

/**
    * 请求处理完成后(渲染视图后)的回调。将在处理程序执行的任何结果上调用,从而允许进行适当的资源清理。
    * @param request
    * @param response
    * @param handler
    * @param ex
    * @throws Exception
    */
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
       RequestHolder.remove();
       log.info("afterCompletion执行。。。");
       return;
   }
}

Application类启动类中配置自定义过滤器和 *

/**
*
* @author zjq
*/
@SpringBootApplication
public class Application extends WebMvcConfigurationSupport {

public static void main(String[] args) {
       SpringApplication.run(ConcurrencyApplication.class, args);
   }

/**
    * 自定义过滤器
    * @return
    */
   @Bean
   public FilterRegistrationBean filterRegistrationBean(){
       FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
       filterRegistrationBean.setFilter(new HttpFilter());
       //设置自定义过滤器拦截的url
       filterRegistrationBean.addUrlPatterns("/threadLocal/*");
       return filterRegistrationBean;
   }

/**
    * 定义自定义 * 原先需要继承WebMvcConfigurerAdapter
    * SpringBoot2.0后WebMvcConfigurerAdapter被定义成过时了,推荐使用继承WebMvcConfigurationSupport
    * @param registry
    */
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");
   }
}

定义调用接口

/**
* ThreadLocal测试controller
* @author zjq
*/
@Controller
@RequestMapping("/threadLocal")
public class ThreadLocalController {

@RequestMapping("/test")
   @ResponseBody
   public Long test() {
       return RequestHolder.get();
   }
}

请求访问验证

访问调用接口http://localhost:8080/threadLocal/test,控制台输出如下:

Java自定义过滤器和 * 实现ThreadLocal线程封闭

来源:https://juejin.cn/post/7128195148076302350

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com