> Java > java지도 시간 > 본문

자바학습에 있어서 스프링의 3대 인터셉터는 무엇인가요?

青灯夜游
풀어 주다: 2018-10-25 17:48:09
앞으로
2888명이 탐색했습니다.

이 글의 내용은 봄의 3대 인터셉터가 무엇인지 소개하는 것입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

Filter

새 TimeFilter 만들기

@Component
public class TimeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("time filter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("time filter start");
        long startTime = System.currentTimeMillis();

        filterChain.doFilter(servletRequest, servletResponse);

        long endTime = System.currentTimeMillis();
        System.out.println("time filter consume " + (endTime - startTime) + " ms");
        System.out.println("time filter end");
    }

    @Override
    public void destroy() {
        System.out.println("time filter init");
    }
}
로그인 후 복사

서버를 시작하고 브라우저에 다음을 입력합니다. http://localhost:8080/hello?name=tom

콘솔에 다음 결과를 출력할 수 있습니다.

time filter start
name: tom
time filter 3 ms 소모
time filter end

필터가 먼저 실행된 후 실제로 HelloController.sayHello() 메서드가 실행되는 것을 볼 수 있습니다.
TimeFilter.doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 메소드의 매개변수에서 볼 수 있듯이 원래 요청 및 응답 개체만 가져올 수 있지만 어떤 Controller와 응답을 가져올 수는 없습니다. 이 요청이 전송된 메소드는 처리되면 Interceptor를 사용하여 이 정보를 얻을 수 있습니다. 原始的 request 和 response对象,不能得到这个请求被哪个 Controller 以及哪个方法处理了,使用Interceptor 就可以获得这些信息。

Interceptor

新建 TimeInterceptor

@Component
public class TimeInterceptor extends HandlerInterceptorAdapter {

    private final NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("startTimeThreadLocal");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("time interceptor preHandle");

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 获取处理当前请求的 handler 信息
        System.out.println("handler 类:" + handlerMethod.getBeanType().getName());
        System.out.println("handler 方法:" + handlerMethod.getMethod().getName());

        MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
        for (MethodParameter methodParameter : methodParameters) {
            String parameterName = methodParameter.getParameterName();
            // 只能获取参数的名称,不能获取到参数的值
            //System.out.println("parameterName: " + parameterName);
        }

        // 把当前时间放入 threadLocal
        startTimeThreadLocal.set(System.currentTimeMillis());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("time interceptor postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        // 从 threadLocal 取出刚才存入的 startTime
        Long startTime = startTimeThreadLocal.get();
        long endTime = System.currentTimeMillis();

        System.out.println("time interceptor consume " + (endTime - startTime) + " ms");

        System.out.println("time interceptor afterCompletion");
    }
}
로그인 후 복사

注册 TimeInterceptor
把 TimeInterceptor 注入 spring 容器

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}
로그인 후 복사

启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:

time filter start
time interceptor preHandle
handler 类:com.nextyu.demo.web.controller.HelloController
handler 方法:sayHello
name: tom
time interceptor postHandle
time interceptor consume 40 ms
time interceptor afterCompletion
time filter consume 51 ms
time filter end
로그인 후 복사
可以看到,filter 先于 interceptor 执行,再到真正执行 HelloController.sayHello() 方法。通过 interceptor 方法上的 handler 参数,我们就可以得到这个请求被哪个 Controller 以及哪个方法处理了。但是不能直接获取到这个方法上的参数值(在这里就是 HelloController.sayHello(String name) 方法参数 name 的值),通过 Aspect 就可以获取到。

Aspcet

新建 TimeAspect

@Aspect
@Component
public class TimeAspect {

    @Around("execution(* com.nextyu.demo.web.controller.*.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {

        System.out.println("time aspect start");

        Object[] args = pjp.getArgs();
        for (Object arg : args) {
            System.out.println("arg is " + arg);
        }

        long startTime = System.currentTimeMillis();

        Object object = pjp.proceed();

        long endTime = System.currentTimeMillis();
        System.out.println("time aspect consume " + (endTime - startTime) + " ms");

        System.out.println("time aspect end");

        return object;
    }

}
로그인 후 복사

启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:

time filter start
time interceptor preHandle
handler 类:com.nextyu.demo.web.controller.HelloController
handler 方法:sayHello
time aspect start
arg is tom
name: tom
time aspect consume 0 ms
time aspect end
time interceptor postHandle
time interceptor consume 2 ms
time interceptor afterCompletion
time filter consume 4 ms
time filter end
로그인 후 복사
可以看到,filter 先执行,再到 interceptor 执行,再到 aspect 执行,再到真正执行 HelloController.sayHello() 方法。
我们也获取到了 HelloController.sayHello(String name) 方法参数 name 的值

Interceptor

New TimeInterceptor🎜
graph TD
httprequest-->filter
filter-->interceptor
interceptor-->aspect
aspect-->controller
로그인 후 복사
🎜TimeInterceptor 등록🎜Spring 컨테이너에 TimeInterceptor 삽입🎜rrreee🎜서버를 시작하고 브라우저에 입력하세요: http://localhost:8080/hello?name=tom🎜할 수 있습니다 control it in 스테이션은 다음과 같은 결과를 출력합니다. 🎜rrreee🎜 인터셉터 이전에 필터가 실행된 후 실제로 HelloController.sayHello() 메서드가 실행되는 것을 볼 수 있습니다. 인터셉터 메소드의 핸들러 매개변수를 통해 어떤 컨트롤러와 요청이 처리된 메소드를 얻을 수 있습니다. 그러나 이 메소드의 매개변수 값은 직접 얻을 수 없습니다. (여기서는 HelloController.sayHello(String name) 메소드 매개변수 이름의 값입니다.) Aspect를 통해 얻을 수 있습니다. 🎜🎜🎜🎜Aspet🎜🎜🎜🎜새 TimeAspect 만들기🎜rrreee🎜서버를 시작하고 브라우저에 다음을 입력합니다. http://localhost:8080/hello?name=tom🎜콘솔에 다음 결과를 출력할 수 있습니다.🎜 rrreee🎜 보시다시피 필터가 먼저 실행되고, 인터셉터가 실행되고, 애스펙트가 실행되고, 실제로 HelloController.sayHello() 메서드가 실행됩니다. 🎜또한 HelloController.sayHello(문자열 이름) 메서드의 매개변수 이름 값을 얻었습니다. 🎜🎜🎜🎜요청 차단 프로세스 다이어그램🎜🎜🎜rrreee

위 내용은 자바학습에 있어서 스프링의 3대 인터셉터는 무엇인가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:cnblogs.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿