一、Filter
这是java规范的一个过滤器,会拦截请求。在SpringBoot中一般有两种配置方式。
这种过滤器拦截并不知道你用的是哪一个Controller处理也不知道你用哪一个方法处理。
通过@Component加入容器
@Component
public class TimerFilter 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 = new Date().getTime();
// 放行
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("time filter:"+(new Date().getTime()-startTime));
System.out.println("time filter finish");
}
@Override
public void destroy() {
System.out.println("Time filter destroy");
}
}
通过配置类加入容器
@Configuration // 声明这个类是配置类
public class WebConfig {
@Bean
public FilterRegistrationBean timeFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new TimerFilter());
// 设置拦截路径
registrationBean.setUrlPatterns(Arrays.asList("/*"));
return registrationBean;
}
}
二、Interceptor
这种是Spring框架自带的拦截器,它会处理自己写的拦截器,也会拦截BasicErrorController。
可以拿到处理的Controller和对应的方法,但是拿不到具体的请求参数。
通过@Component加入容器
@Component
public class TimeInterceptor implements HandlerInterceptor {
/**
* 控制器方法处理之前执行
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
System.out.println("preHandle");
// 获取处理器的类名
System.out.println(((HandlerMethod) handler).getBean().getClass().getName());
// 获取调用的方法名
System.out.println(((HandlerMethod) handler).getMethod().getName());
httpServletRequest.setAttribute("startTime", new Date().getTime());
return false;
}
/**
* 控制器方法处理之后执行
* 控制器方法处理时抛异常调用则不执行
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
Long startTime = (Long) httpServletRequest.getAttribute("startTime");
System.out.println("time interceptor 耗时" + (new Date().getTime() - startTime));
}
/**
* 控制器方法抛不抛异常都会被执行
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion");
Long startTime = (Long) httpServletRequest.getAttribute("startTime");
System.out.println("time interceptor 耗时" + (new Date().getTime() - startTime));
System.out.println("ex is" + e);
}
}
通过配置类加入容器
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器有顺序之分
registry.addInterceptor(timeInterceptor);
}
}
三、Aspect
@Aspect
@Component
public class TimeAspect {
// 环绕通知
@Around("execution(* cn.yujiago.controller.UserController.*(..))")
public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("time aspect start");
// 获取请求参数
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg : args) {
System.out.println(arg.getClass().getName());
System.out.println("arg is " + arg);
}
long startTime = new Date().getTime();
// 执行目标方法,并获取返回值
Object obj = proceedingJoinPoint.proceed();
System.out.println("time aspect 耗时" + (new Date().getTime() - startTime));
System.out.println("time aspect end");
return obj;
}
}
过滤器(Filter):可以拿到原始的http请求,但拿不到请求的控制器和请求控制器中方法的信息。
拦截器(Interceptor):可以拿到请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象。