继上篇实现路由功能 出现的小瑕疵

一,在上一篇博客中,我们已经可以实现自定义注解实现路由功能了,但是这里实际上有点儿小瑕疵,那就是我们所些的Interceptor并没有被加入到自定义的HandlerMappingHandlerTest中来,这是为啥呢?

1,因为我们在注册为一个Bean的时候,并没有对Interceptor属性进行设置。

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public HandlerMapping handlerMappingTest() {
        return new HandlerMappingHandlerTest();
    }
}

2,这就导致了内部没有Interceptor,这时候,如果我们自定义了一个Interceptor。那么这个interceptor在我们自己的HandlerMappingHandlerTest路由功能中是不起作用的。

public class InterceptorTest implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

3,也就是说这是两个体系。对于路由功能的解析和interceptor的注册是一体的。但是不同的解析规则,需要自己添加Interceptor,Spring是不会将我们注册给WebMvcConfigurer的Interceptor拿给我们来用的。

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public HandlerMapping handlerMappingTest() {
        HandlerMappingHandlerTest handlerTest = new HandlerMappingHandlerTest();
        handlerTest.setInterceptors(new InterceptorTest());// 这里注册给我们自定义的HandlerMappingHandlerTest
        return handlerTest;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new InterceptorTest());//这里是注册给Spring默认的RequestMappingHandlerMapping
    }
}

二,那么问题来了,为什么Spring默认的RequestMappingHandlerMapping这个类可以拿到interceptor呢?

答案是因为RequestMappingHandlerMapping的初始化是在WebMvcConfigurationSupport类中完成的。

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
        @Bean
	public RequestMappingHandlerMapping requestMappingHandlerMapping() {
		RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
		mapping.setOrder(0);
		mapping.setInterceptors(getInterceptors());//!!!这里调用了下面的代码!!!
		mapping.setContentNegotiationManager(mvcContentNegotiationManager());
		mapping.setCorsConfigurations(getCorsConfigurations());
                。。。// 省略
                {
                    protected final Object[] getInterceptors() {//!!!调用了这里!!!
		        if (this.interceptors == null) {
			    InterceptorRegistry registry = new InterceptorRegistry();//我们自定义的所有interceptor都在这里。但是这个方法的get属性是protected的,外部拿不到
			    addInterceptors(registry);
			    registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
			    registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
			    this.interceptors = registry.getInterceptors();
		        }
		        return this.interceptors.toArray();
                    }
                }

        }
}

 

而WebMvcConfigurationSupport内部可以调用所有注册到InterceptorRegistry的信息,也就是下面接口的内容,其实就是我们可以配置的内容

public interface WebMvcConfigurer {


	default void addFormatters(FormatterRegistry registry) {// 格式化
	}

	default void addInterceptors(InterceptorRegistry registry) {// 拦截器
	}

	default void addResourceHandlers(ResourceHandlerRegistry registry) {//资源处理器
	}

	default void addCorsMappings(CorsRegistry registry) {// 跨域
	}

	default void addViewControllers(ViewControllerRegistry registry) {
	}

	default void configureViewResolvers(ViewResolverRegistry registry) {
	}

	default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {// 参数解析器
	}

	default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {//返回值处理器,添加自定义的返回值处理器可是实现统一回包格式的功能
	}

}

但是在包外这些内容去都是拿不到的,

/**
 * Configuration equivalent to {@code @EnableWebMvc}.
 */
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
    @Bean
    @Primary
    @Override
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        // Must be @Primary for MvcUriComponentsBuilder to work
        return super.requestMappingHandlerMapping();// 这里注册为Bean,我们一般是在自己写的config中注册为Bean, 但是在这里注册可以拿到注册器,参数解析器,返回值处理器等。但是在包外的我们就拿不到,这就是亲儿子的待遇啊!!!
    }
}

所以其实这里可以给Spring一个小建议,那就是给

org.springframework.web.servlet.config.annotation.InterceptorRegistry这个类增加各种get方法。!!!

demo链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值