Filter
这个是Servlet的过滤器,基于回调函数实现,实现接口Filter就可以,可以使用@Compoent将实现的Filter托管给spring的ioc容器,也可以在@Configuration注解实现的配置类中注册,可以使用如下方式进行代码注册:
FilterRegistrationBean registrationBean = new FilterRegistratonBean();
XXFilter xxFilter = new XXFilter();
registrationBean.setFilter(xxFilter);
List<String> urls = new ArrayList<>();
urls.add("/*");
registrationBean.setUrlPatterns(urls);
return registrationBean;
它可以拿到原始的HTTP请求,但是拿不到请求的控制器和请求的控制器中的方法的信息
HandlerInterceptor
这是spring的拦截器,直接实现HandlerInterceptor就可以,可以使用@Component注解将实现的拦截器注入spring的ioc容器,也可以使用基于@Configuration注解实现的配置类来注册拦截器,底层基于反射,采用责任链模式下面是一般实现代码:
@Configuration
public class webConfig implements WebMvcConfigurer {
@Autowired
private XXintercepter xxInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(xxInterceptor).addPathPatterns("/**");;
}
}
它可以拿到请求的控制器和方法,却拿不到请求方法的参数
Aspect
使用环绕通知切入要切入的类,使用注解@Aspect在类上
使用@Pointcut("execution(* com.xx..*(..))")
或者@Around("execution("* com.xx..*(..))")在方法上
面向AOP可以基于注解式和方法规则式拦截,注解式是自己定义一个注解,在需要拦截的方法上使用该注解,方法规则式是根据包路径来匹配拦截 。AOP底层主要基于到动态代理实现
package com.cenobitor.aop.aspect;
import com.cenobitor.aop.annotation.Action;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class LogAspect {
@Pointcut("@annotation(com.cenobitor.aop.annotation.Action)")
public void annotationPoinCut(){}
@After("annotationPoinCut()")
public void after(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截 "+action.name());
}
@Before("execution(* com.cenobitor.aop.service.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
}
它可以获取拦截的方法的参数,但是拿不到http请求和响应的对象。