微服务中引入公共拦截器
本文使用的微服务版本为springcloudAlbaba :2021.0.4.0
微服务工程,一般公共的东西都放入一个工程,别的微服务都会引入这个工程,比如common-service,那么就可以在这个工程编写一个拦截器:,比如:
public class UserInfoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//从请求头中获取用户信息String header = request.getHeader("user-info");if(StrUtil.isNotBlank(header)){//这里UserContext的user是个ThreadLocalUserContext.setUser(Long.valueOf(header));}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserContext.removeUser();} }
这里是做个用户信息获取的拦截器,从请求头中获取用户信息,然后塞入ThreadLocal中,供后续业务使用。
定义完了,为了使它生效,编译一个配置类:
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());} }
然后利用springboot自动装配的原理,在spring.factroies中添加MvcConfig的全路径,
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.*.common.config.MvcConfig
这里*用你实际的就好,别真的写*。
这样所有引入common-service依赖的微服务都添加了这个拦截器。
但是注意如果某个微服务启动报错,可能是你的某这个微服务没有引入springmvc的依赖,比如网关微服务,网关不需要springmvc的依赖,也不需要这个拦截器,
我们同样利用springboot自动装配ConditionalOnClass注解的特性来让网关不引入这个拦截器。只需要加上一段@ConditionalOnClass(DispatcherServlet.class)即可
@Configuration @ConditionalOnClass(DispatcherServlet.class) public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserInfoInterceptor());} }
DispatcherServlet是springmvc的核心类,使用ConditionalOnClass,即判断当前有没有引入springmvc的依赖来判断是否引入MvcConfig 这个配置类,网关没有springmvc的依赖,这样这个配置类就不会生效。