过滤器,拦截器,SpringAop执行顺序详解(基于Springboot2.0)

结论:能看懂就不用往下翻了,不过点个赞还是很nice的

====doFilter====
====preHandle====
=====around02 start====
====before02=====
=====around01 start====
====before01=====
====method run====
=====around01 end====1
=====after01====
=====afterReturning01====1
=====around02 end====2
=====after02====
=====afterReturning02====2
====postHandle====
====afterCompletion====

1、Spring Aop

aop怎么声明就不用啰嗦了,注意:

通知声明类上加上:@Aspect @Component

单个通知类,上代码:

@Aspect
@Component
@Slf4j
public class TestAspect01 {

    @Pointcut("execution(* com.springboot.netty.spingbootnetty.singleTon.UserService.*(..))")
    public void flag() {
    }

    @Before("flag()")
    public void before(JoinPoint joinPoint) {
        System.out.println("====before01=====");
    }

    @After("flag()")
    public void after(JoinPoint joinPoint) {
        System.out.println("=====after01====");
    }

    @AfterReturning(value = "flag()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("=====afterReturning01====" + result);
    }

    @AfterThrowing(pointcut = "flag()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        System.out.println("=====afterThrowing01====");
    }

    @Around("flag()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("=====around01 start====");
        String result = null;
        result = (String) joinPoint.proceed();
        System.out.println("=====around01 end====" + result);
        return result;
    }


}

单个通知类执行顺序,正常情况:result为被拦截方法的返回值,返回通知想要取到返回值,前提是你必须在环绕通知中把result返回出去)

=====around01 start====
====before01=====
====method run====
=====around01 end====result=1
=====after01====
=====afterReturning01====result=1

单个通知类执行顺序,异常情况:

=====around01 start====
====before01=====

====method run====
=====after01====
=====afterThrowing01====

多个通知类,上代码:

注意加了@Order注解,数字越小执行越早

@Aspect
@Component
@Slf4j
@Order(1)
public class TestAspect02 {

    @Pointcut("execution(* com.springboot.netty.spingbootnetty.singleTon.UserService.*(..))")
    public void flag() {
    }

    @Before("flag()")
    public void before(JoinPoint joinPoint) {
        System.out.println("====before02=====");
    }

    @After("flag()")
    public void after(JoinPoint joinPoint) {
        System.out.println("=====after02====");
    }

    @AfterReturning(value = "flag()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("=====afterReturning02====" + result);
    }

    @AfterThrowing(value = "flag()")
    public void afterThrowing(JoinPoint joinPoint) {
        System.out.println("=====afterThrowing02====");
    }

    @Around("flag()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("=====around02 start====");
        String result = null;
        result = (String) joinPoint.proceed();
        result = "2";
        System.out.println("=====around02 end====" + result);
        return result;
    }


}

单个通知类执行顺序,正常情况:

=====around02 start====
====before02=====
=====around01 start====
====before01=====
====method run====
=====around01 end====result=1
=====after01====
=====afterReturning01====result=1
=====around02 end====result=2
=====after02====
=====afterReturning02====result=2

单个通知类执行顺序,异常情况:

=====around02 start====
====before02=====
=====around01 start====
====before01=====

====method run====
=====after01====
=====afterThrowing01====
=====after02====
=====afterThrowing02====

总结:

spring AOP就是面向切面编程,什么是切面,看图:

过滤器,拦截器,SpringAop执行顺序详解(基于Springboot2.0)_第1张图片

这就是为什么先执行的通知类后执行完的原因了!!!

2、拦截器

注意一点:拦截器需要注册

注册拦截器:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private MyInteceptor myInteceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInteceptor).addPathPatterns("/**");
    }

}

上代码:

@Component
public class MyInteceptor implements HandlerInterceptor{


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("====preHandle====");
        return true;
    }

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

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("====afterCompletion====");
    }
}

aop、拦截器执行顺序:

====preHandle====
=====around02 start====
====before02=====
====method run====
=====around02 end====2
=====after02====
=====afterReturning02====2
====postHandle====
====afterCompletion====

3、过滤器

没什么好说的,上代码:

@Component
@WebFilter(filterName = "testFilter", urlPatterns = "/**")
public class TestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("----------------------->过滤器被创建");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        String requestURI = req.getRequestURI();
        System.out.println("====doFilter====:请求地址"+requestURI);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("----------------------->过滤器被销毁");
    }

}

aop、拦截器、过滤器执行顺序:

====doFilter====
====preHandle====
=====around02 start====
====before02=====
====method run====
=====around02 end====2
=====after02====
=====afterReturning02====2
====postHandle====
====afterCompletion====

结论:

粒度:过滤器 >> 拦截器 >> aop

 

你可能感兴趣的:(过滤器,拦截器,SpringAop执行顺序详解(基于Springboot2.0))