spring boot springMVC擴展配置 。WebMvcConfigurer ,WebMvcConfigurerAdapter


摘要:

  在spring boot中 MVC這部分也有默認自動配置,也就是說我們不用做任何配置,那么也是OK的,這個配置類就是 WebMvcAutoConfiguration,但是也時候我們想設置自己的springMvc配置怎么辦呢 。我們也可以寫個自己的配置類,繼承 WebMvcConfigurer 重寫需要的配置方法 。在spring boot 早期是繼承WebMvcConfigurerAdapter ,但是高版已標上注解@Deprecated,注意:在配置類中不要標注:@EnableWebMvc,否則,spring boot的配置全部失效,只留自己擴展配置。

示例:

這里已高版為主 繼承WebMvcConfigurer,WebMvcConfigurer 接口中的方法都是默認的方法,可以覆蓋,也可以不實現 ,加一個視圖解析配置 ,解析success請求路勁,返回success頁面。如下代碼:

@Configuration
public class MyMvcConfig Implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
       // super.addViewControllers(registry);
        //瀏覽器發送 /success請求來到 success
        registry.addViewController("/success").setViewName("success");
    }
}

 

 

代碼淺析:

1.首先我們來看看WebMvcAutoConfiguration這個配置類,這個配置了有首頁的默認路勁,還有一些靜態資源路勁,而這些方法在它的一個內部類中,如下代碼(刪除了部分代碼):



@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
    ....//省略部分代碼
    @Configuration
    @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) // 導入了EnableWebMvcConfiguration這個類 addResourceHandlers方法
    @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
    @Order(0)
    public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
       
    ...//省略部分代碼
        public void addResourceHandlers(ResourceHandlerRegistry registry) {//實現WebMvcConfigurer 這個類的
            if(!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if(!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if(!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }

}

 

可以看到,內部類 WebMvcAutoConfigurationAdapter 標記 @Configuration,並導入另一個內部類 @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}),我們看下這個類,如下代碼:
@Configuration
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
        private final WebMvcProperties mvcProperties;
        private final ListableBeanFactory beanFactory;
        private final WebMvcRegistrations mvcRegistrations;
     ...// 省略
}

 

重點在它的父類, DelegatingWebMvcConfiguration  代碼如下 (寫了幾個案列方法,其他代碼省略。)。
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

     ...//省略
    /**
     * 從容器中拿到所有 WebMvcConfigurer 的實現類。遍歷添加到  configurers 
     * [required description]
     * @type {[type]}
     */
    @Autowired( required = false ) // 自動裝配
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
        if(!CollectionUtils.isEmpty(configurers)) {
            this.configurers.addWebMvcConfigurers(configurers);
        }

    }
    ...//省略
    /**
     * 當調用addResourceHandlers 時 ,調用的 成員configurers的 addResourceHandlers
     * [addResourceHandlers description]
     * @param {[type]} ResourceHandlerRegistry registry [description]
     */
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        this.configurers.addResourceHandlers(registry);
    }
    ...//省略
}

 

來看看 WebMvcConfigurerComposite 的 addResourceHandlers的方法做了什么 :
class WebMvcConfigurerComposite implements WebMvcConfigurer {

    private final List<WebMvcConfigurer> delegates = new ArrayList<WebMvcConfigurer>();

    @Override
    public void addViewControllers(ViewControllerRegistry registry) { // 遍歷 把 所有WebMvcConfigurer的 addViewControllers方法調用一遍
        for (WebMvcConfigurer delegate : this.delegates) {
            delegate.addViewControllers(registry);
        }
    }
}

 

看到這里我們知道 ,不管是spring boot中實現的 WebMvcConfigurer 類,還是我們自己實現 WebMvcConfigurer ,只要我們把實現類注入到容器中,就會被 注入 WebMvcConfigurerComposite 這個類成員變量 delegates中
。而 WebMvcConfigurerComposite 有是實現了 WebMvcConfigurer  。當調用 WebMvcConfigurer中 xxx方法的,就會遍歷 delegates 中所有 WebMvcConfigurer  的方法xxx 。那我們的擴展配置
MyMvcConfig 也就被調用了。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM