欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Filter Interceptor AOP

程序员文章站 2022-07-15 15:39:25
...

过滤器: Filter

Filter类

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("------------filter init------------");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("------------doFilter start------------");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("------------doFilter stop------------");
    }

    @Override
    public void destroy() {
        System.out.println("------------filter destroy------------");
    }
}

[email protected] | @WebFilter 方式

// @Component 
@WebFilter(filterName="myFilter",urlPatterns={"/*"})
public class MyFilter implements Filter {}

[email protected]方式

import org.baozi.aop.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;


@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean myilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        // 设置filter
        bean.setFilter(new MyFilter());
        // 设置urls
        List<String> urls = new ArrayList<>();
        urls.add("/*");
        bean.setUrlPatterns(urls);
        return bean;
    }

}

测试控制器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/myMethod")
    public void myMethod() {
        System.out.println("controller myMethod");
    }

}

拦截器: Interceptor

多个拦截器时的执行顺序:拦截器1的preHandler -> 拦截器2的preHandler -> 控制器方法 -> 拦截器2的postHandler -> 拦截器1的postHandler -> 拦截器2的afterCompletion -> 拦截器1的afterCompletion....

  1. 配置文件方式
①.实现HandlerInterceptor接口
②.配置拦截器的拦截规则
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="" />
    <bean  />
  </mvc:interceptor>
<mvc:interceptors>
  1. 注解方式
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class MyInterceptor 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");
    }
}

配置类

import org.baozi.interceptor.MyInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyConfiguration implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor);
    }
}

测试控制器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/myMethod")
    public void myMethod() {
        System.out.println("controller myMethod");
    }

}

切面编程: AOP

原理:将散落于各个类中的公共部分抽取出来做成切面类, 与具体实现解耦,使用JDK动态代理和CGLIB代理实现。

注解式:
@Before
@After(最终通知,返回和异常)
@AfterReturning(后置通知,只有返回了才通知)
@AfterThrowing
@Around
方法参数为ProceedingJoinPoint。

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

切面类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component
public class MyAspect {

    @Around("execution(public * org.baozi.web.MyController.*(..))")
    public Object aopMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("------------aop start");

        // 查看连接点信息
        // Join Point kind : method-execution
        System.out.println("Join Point kind : " + joinPoint.getKind());
        // Signature declaring type : org.baozi.web.MyController
        System.out.println("Signature declaring type : " + joinPoint.getSignature().getDeclaringTypeName());
        // Signature name : myMethod
        System.out.println("Signature name : " + joinPoint.getSignature().getName());
        // Arguments : []
        System.out.println("Arguments : " + Arrays.toString(joinPoint.getArgs()));
        // Target class : org.baozi.web.MyController
        System.out.println("Target class : " + joinPoint.getTarget().getClass().getName());
        // This class : org.baozi.web.MyController$$EnhancerBySpringCGLIB$$4651a897
        System.out.println("This class : " + joinPoint.getThis().getClass().getName());

        // 执行方法
        Object o = joinPoint.proceed();

        System.out.println("------------aop stop");
        return o;
    }

}

控制器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/myMethod")
    public void myMethod() {
        System.out.println("controller myMethod");
    }

}

Filter Interceptor AOP区别

Filter只能拿到服务器请求响应,哪个控制器和哪个方法处理的并不知道
Interceptor能拿到服务器请求和响应,类名和方法名,但是拿不到参数具体的值
AOP能拿到参数的值,但是拿不到服务器请求与响应。
从外到内 Filter -> Interceptor -> ControllerAdvice -> Aspect -> Controller

Filter依赖Servlet容器,基于回调函数,过滤范围大(包括请求与静态资源)
拦截器依赖框架,基于反射,只拦截请求。
AOP是方法级的,增强方法。

转载于:https://www.jianshu.com/p/bd7727b09110