Java之过滤器Filter、拦截器Interceptor与面向切面AOP
Filter的使用
@Component
@WebFilter(urlPatterns = {"/*"})
public class CustomFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 在请求进入容器后 servlet前System.out.println("CustomFilter doFilter 前");// 放行请求chain.doFilter(request, response);// 请求离开servlet后System.out.println("CustomFilter doFilter 后");}
}
Interceptor的使用
-
自定义拦截器
public class CustomInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前进行拦截处理 返回 true 表示继续处理请求,返回 false 则表示拦截请求System.out.println("CustomInterceptor preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理之后调用,但在视图被渲染之前(Controller方法调用之后)System.out.println("CustomInterceptor postHandle 请求处理之后调用,但在视图被渲染之前(Controller方法调用之后)");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 整个请求处理完毕后调用,即视图渲染完毕或者发生异常时调用System.out.println("CustomInterceptor afterCompletion 整个请求处理完毕后调用,即视图渲染完毕或者发生异常时调用");} }
-
基于springmvc编写配置类
@Configuration public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/**"); // 设置拦截的路径}}
AOP的使用
-
引入依赖
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId> </dependency>
-
编写配置类
@Aspect @Component public class HelloAop {@Pointcut("execution(* com.lxw.afi.controller.HelloController.hello(..))")public void pointcut() {}@Before("pointcut()")public void before(JoinPoint joinPoint) {System.out.println("@Before");}@AfterThrowing("pointcut()")public void afterThrowing() {System.out.println("@AfterThrowing");}@AfterReturning("pointcut()")public void afterReturning() {System.out.println("@AfterReturning");}@After("pointcut()")public void after() {System.out.println("@After");}@Around("pointcut()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object result;try {System.out.println("@Around...方法执行前");result = pjp.proceed();System.out.println("@Around...方法执行后");} catch (Throwable throwable) {System.out.println("@Around...抛出异常后");throw throwable;} finally {System.out.println("@Around...finally");}return result;}
区别
- Filter是 servlet提供的Interceptor和AOP是spring提供的
- Filter和Interceptor是基于URL进行的,AOP基于类的元数据(包、类、方法名、参数等)
- Filter、Interceptor可以拦截所有请求action和静态资源[css,js…],AOP只能拦截action请求
- 执行顺序Filter>Interceptor>AOP
- 细致程度AOP>Interceptor>Filter
使用场景
在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是aop。
比如:
权限校验,一般情况下,所有的请求都需要做登陆校验,此时就应该使用过滤器在最顶层做校验;日志记录,一般日志只会针对部分逻辑做日志记录,而且牵扯到业务逻辑完成前后的日志记录,因此使用过滤器不能细致地划分模块,此时应该考虑拦截器,然而拦截器也是依据URL做规则匹配,因此相对来说不够细致,因此我们会考虑到使用AOP实现,AOP可以针对代码的方法级别做拦截,很适合日志功能。