SpringBoot扩展自定义SringMVC配置需要继承WebMvcConfigurer接口,并添加@Configuration注解,可以让SpringBoot自动将我们自定义的MVC配置纳入Spring管理。如果添加@@EnableWebMvc注解,则SpringBoot不会导入它自身的自动配置功能。 1、自定义属性编辑器(PropertyEditor)的配置方法2、我们详解WebMvcConfigurer接口的方法使用:

package com.iclnetwork.springboot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义MVC配置
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    /** 引入环境变量 */
    @Autowired
    private Environment environment;
    /** 信息源 */
    @Autowired
    private MessageSource messageSource;

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {

    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

    }

    /**
     * 配置异步执行器
     * @param configurer
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
        // 线程分组名称
        asyncTaskExecutor.setThreadGroupName(environment.getProperty("async.task.threadGroupName", String.class, "AsyncTask"));
        // 核心线程的数量,初始化不会创建线程
        asyncTaskExecutor.setCorePoolSize(environment.getProperty("async.task.corePoolSize", Integer.class, 5));
        // 线程的最大数量,包括闲空与活动的线程
        asyncTaskExecutor.setMaxPoolSize(environment.getProperty("async.task.maxPoolSize", Integer.class, 100));
        // 线程队列的容量,少于“核心数量”时首选创建线程,大于“核心数量”时首选加入队列,其次再继续创建线程直到等于“最大数量”
        asyncTaskExecutor.setQueueCapacity(environment.getProperty("async.task.queueCapacity", Integer.class, 20));
        // 空闲线程存在的秒数,大于“核心数量”时监控,配合“AllowCoreThreadTimeOut”配置
        asyncTaskExecutor.setKeepAliveSeconds(environment.getProperty("async.task.keepAliveSeconds", Integer.class, 300));
        // 等待线程任务的最大秒数,容器关闭前触发,配合“WaitForTasksToCompleteOnShutdown”配置
        asyncTaskExecutor.setAwaitTerminationSeconds(environment.getProperty("async.task.awaitTerminationSeconds", Integer.class, 60));
        // 禁用核心线程超时,即允许核心线程永久空闲
        asyncTaskExecutor.setAllowCoreThreadTimeOut(false);
        // 启用容器关闭前等待线程任务完成
        asyncTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 异常拒绝处理策略,无线程可用时抛“RejectedExecutionException”异常
        asyncTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        asyncTaskExecutor.initialize();
        configurer.setTaskExecutor(asyncTaskExecutor);
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

    }

    /**
     * 添加类型转换器和格式化器
     * @param registry
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
    }

    /**
     * 增加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //        registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin/**");
    }

    /**
     * 添加静态资源处理
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //从配置文件中读取enabledDevelopment属性值
        boolean enabledDevelopment = environment.getProperty("enabledDevelopment", Boolean.class, false);
        if (enabledDevelopment) {
            // 资源处理器
            registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html").setCachePeriod(0);
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/").setCachePeriod(0);
        }
    }

    /**
     * 跨域支持
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods("GET", "POST", "DELETE", "PUT").maxAge(3600 * 24);
    }

    /**
     * 增加视图控制器
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //当请求/时,spring MVC会自动返回home模板。
        registry.addViewController("/").setViewName("home");
        //当求/index时,spring MVC会自动从定向到/home地址上。
        registry.addRedirectViewController("/index", "/home");
    }

    /**
     * 配置视图解析器
     * SpringBoot 可以通过我们导入的模板启动器类型来自动配置,
     * 如果您使用的是Thymeleaf或者Freemarker启动器,SpringBoot会给我们讲此功能自动配置好,这里无需配置。
     * 可以参考WebMvcProperties和View在配置文件(application.properties)中修改参数
     * @param registry
     * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties
     * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.View
     * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        //freemarker配置样例
        //        ViewResolver viewResolver = new FreeMarkerViewResolver();
        //        // 内容类型,解决中文乱码
        //        viewResolver.setContentType("text/html; charset=UTF-8");
        //        // 后缀
        //        viewResolver.setSuffix(".ftl");
        //        registry.viewResolver(viewResolver);
        //        // BeanName视图解析器
        //        registry.beanName();
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

    }

    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {

    }

    /**
     * 消息转换器 将请求参数转换成特定的类
     * SpringBoot的自动配置功能已经将这块功能自动配置了,可以通过WebMvcProperties的属性在配置文件(application.properties)中设置
     * dateFormat日期转换格式
     * @param converters
     * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties
     * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //        ObjectMapper objectMapper = new ObjectMapper().setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        //        for (HttpMessageConverter<?> messageConverter : converters) {
        //            if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
        //                // 对象映射器
        //                ((MappingJackson2HttpMessageConverter) messageConverter).setObjectMapper(objectMapper);
        //            }
        //        }
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

    }

    /**
     * 配置异常处理
     * @param resolvers
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        // 是否启用开发模式
        boolean enabledDevelopment = environment.getProperty("enabledDevelopment", Boolean.class, false);
        // 异常映射
        Properties exceptionMappings = new Properties();
        // 状态码映射
        Properties statusCodes = new Properties();
        if (!enabledDevelopment) {
            exceptionMappings.setProperty("org.apache.shiro.authz.UnauthorizedException", "/unauthorized");
            statusCodes.setProperty("/unauthorized", String.valueOf(HttpServletResponse.SC_FORBIDDEN));
        }
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
        // 默认错误视图
        if (enabledDevelopment) {
            exceptionResolver.setDefaultErrorView("/exception");
        } else {
            exceptionResolver.setDefaultErrorView("/error");
        }
        // 默认状态代码
        exceptionResolver.setDefaultStatusCode(500);
        // 阻止响应缓存
        exceptionResolver.setPreventResponseCaching(true);
        // 警告日志类型
        exceptionResolver.setWarnLogCategory("org.springframework.web.servlet.handler.SimpleMappingExceptionResolver");
        exceptionResolver.setExceptionMappings(exceptionMappings);
        exceptionResolver.setStatusCodes(statusCodes);
        resolvers.add(exceptionResolver);
    }

    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

    }

    /**
     * 验证器,SpringBoot已自动配置,这里无需配置,以下是配置实例
     * @return
     */
    @Override
    public Validator getValidator() {
        //        LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
        //        // 生产者类
        //        validator.setProviderClass(HibernateValidator.class);
        //        validator.setValidationMessageSource(messageSource);
        //        return validator;
        return null;
    }

    @Override
    public MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

还有一些方法后续会持续更新。
注:SpringBoot对以上的所有功能都有一个默认配置(WebMvcAutoConfiguration),如果它给定的默认配置不能满足我们的需求,我们可以根据以上的方法进行扩展。