今天想测试下线上代码,能否正常的执行未登录的拦截。所以把拦截器的代码给开放出来,但是没想到线上代码addInerceptors(InterceptorRegistry registry) 这个方法一直不被执行。
@EnableWebMvc@Configuration@Slf4jpublic class WebConfig implements WebMvcConfigurer { @Bean public UnLoginInterceptor unLoginInterceptor(){ return new UnLoginInterceptor(); } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "DELETE", "PUT", "HEAD", "OPTIONS") .maxAge(3600); } @Override public void addInterceptors(InterceptorRegistry registry) { log.info("加载拦截器"); //添加拦截器并添加拦截器的拦截路径 registry.addInterceptor(unLoginInterceptor()).addPathPatterns("/api/**") .excludePathPatterns("/api/web/login/**") .excludePathPatterns("/api/web/dictionary/**") .excludePathPatterns("/api/web/perm/listAllPerm"); }}
这里请大家注意@EnableWebMvc这个注解。问题就出在这里了。跟进这个注解会发现它有一个代理类DelegatingWebMvcConfiguration。
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Import({DelegatingWebMvcConfiguration.class})public @interface EnableWebMvc {}
再跟进会发现它继承了 WebMvcConfigurationSupport。
@Configurationpublic class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); public DelegatingWebMvcConfiguration() { }}
请大家记住这个类WebMvcConfigurationSupport。
---------------------------------------------------------------------
其实Springboot的自动装配依靠的是WebMvcAutoConfiguration类和其类中静态内部类WebMvcAutoConfigurationAdapter以及EnableWebMvcConfiguration构成了自动装配。
那么可以很清楚的看到WebMvcAutoConfiguration类名上面有一个注解@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})。意思就是如果当前的Spring类中不包含WebMvcConfigurationSupport这个类,那么会走自动装配。否则就需要自己去装配bean。
@Configuration@ConditionalOnWebApplication( type = Type.SERVLET)@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})@AutoConfigureOrder(-2147483638)@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})public class WebMvcAutoConfiguration { public static final String DEFAULT_PREFIX = ""; public static final String DEFAULT_SUFFIX = ""; private static final String[] SERVLET_LOCATIONS = new String[]{"/"}; public WebMvcAutoConfiguration() { }}
看到这里,问题就迎刃而解了,就是这个注解@EnableWebMvc导致了我的拦截器不起作用。
那么问题来了?为什么本地的可以被拦截到,而线上的代码不能被拦截呢?其实我也不知道。我只是找到了问题的所在。但是解释不了为什么本地跟线上的不一样。我怀疑是代码打包的有问题,然后用反编译工具,比对代码。发现的确代码都是被成功打包了。所以究竟是什么原因导致线上代码拦截器不起作用?我也不知道。嘻嘻嘻!望指教。。。