>  기사  >  Java  >  Java 사용자 정의 필터 및 인터셉터는 ThreadLocal 스레드 클로저를 구현합니다.

Java 사용자 정의 필터 및 인터셉터는 ThreadLocal 스레드 클로저를 구현합니다.

WBOY
WBOY앞으로
2023-05-15 23:40:05902검색

스레드 클로저

스레드 클로저는 일반적으로 다음 세 가지 방법을 채택합니다.

  • 임시 스레드 클로저: 프로그램 제어 구현, 최악, 무시

  • 스택 클로저: 지역 변수, 동시성 문제 없음

  • ThreadLocal 스레드 클로저: 특히 좋은 클로저 방법

방법 2가 가장 일반적으로 사용됩니다. 변수는 인터페이스에서 정의됩니다. 이 기사에서는 주로 방법 3을 설명합니다. SpringBoot 프로젝트는 사용자 정의 필터와 인터셉터를 통해 ThreadLocal 스레드 클로저를 구현합니다. 필터 인터페이스 사용자 정의 필터를 구현하고 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();
    }

}

Customized 필터

Customized 인터셉터는 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() {

    }
}

Customized 인터셉터

Customized 인터셉터는 컨트롤러가 해당 내용을 제거합니다. 메모리 오버플로를 방지하기 위해 스레드를 사용한 후의 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;
    }
}

응용 프로그램 클래스 시작 클래스에서 사용자 정의 필터 및 인터셉터 구성

/**
 * 
 * @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 스레드 클로저를 구현합니다.

위 내용은 Java 사용자 정의 필터 및 인터셉터는 ThreadLocal 스레드 클로저를 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제