1、Filter、HandlerInterceptor和MethodInterceptor的区别
在Web开发中,我们经常会用到拦截器。而常用用于实现拦截的有:Filter、HandlerInterceptor、MethodInterceptor。我们也简单了解一下他们的区别:
1、Filter是Servlet规范规定的,不属于spring框架,也是用于请求的拦截。我们在写Filter时需要自己配置拦截的urlPatterns,它适合更粗粒度的拦截,在请求前后做一些编解码处理、Session验证等。
2、HandlerInterceptoer拦截的是请求地址,功能能跟Filter类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。所以针对请求地址做一些验证、预处理等操作比较合适。也可以用作计算一个请求的相应时间等。【必须过DispatcherServlet的请求才会被拦截】
3、MethodInterceptor利用的是AOP的实现机制,它拦截的目标是方法,即使不是controller中的方法。实现MethodInterceptor拦截器大致也分为两种,一种是实现MethodInterceptor接口,另一种利用AspectJ的注解或配置。
2、MethodInterceptor+自定义注解实例
目前MyAnno annotation = method.getAnnotation(MyAnno.class);获取的值一直为null
2.1、自定义接口
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String name();
int age();
}
2.2 拦截器
@Component
@Slf4j
public class MyInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Method method = methodInvocation.getThis().getClass()
.getDeclaredMethod(methodInvocation.getMethod().getName(),methodInvocation.getMethod().getParameterTypes());
Object object = null;
try {
object = methodInvocation.proceed();
ResponseData responseData = (ResponseData) object;
if (Objects.equals(responseData.getRespCode(), ResponseEnum.SUCCESSS.getCode())) {
// todo annotation 一直为null
MyAnno annotation = method.getAnnotation(MyAnno.class);
if (ObjectUtils.isNotEmpty(annotation)) {
if (ObjectUtils.isEmpty(annotation.name())) {
throw new BizException(BizErrorCode.PARAM_ERROR, "积分任务类型参数错误");
}
System.out.println("{} 今年 {} 岁了"+annotation.name()+annotation.age());
}
}
}catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
System.out.println("添加了注解");
return object;
}
}
2.3 aop配置切点增强
@Configuration
public class MyInterceptorConfig {
public static final String traceExecution = "execution(* com.homedo.microservice.crm.mis.basicservice.remote..*.*(..))";
@Resource
private MyInterceptor myInterceptor;
@Bean
public DefaultPointcutAdvisor myAdvisor(){
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(traceExecution);
// 配置增强类advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(myInterceptor);
return advisor;
}
}