• MVC自动配置原理


    目录

    一、官网阅读

    二、ContentNegotiatingViewResolver  (内容协商视图解析器)

    ViewResolver 的源码: 

    resolveViewName 

    getCandidateViews 

    三、Formatter 转换器和格式化器

    四、修改SpringBoot的默认配置

    五、扩展使用SpringMVC

    ⚪实现视图跳转


    一、官网阅读

    官网地址:Spring Boot Reference Documentation

    二、ContentNegotiatingViewResolver  (内容协商视图解析器

    ContentNegotiatingViewResolver  实现了视图解析器的类,就可以把它看做视图解析器

    ViewResolver 的源码: 

    1. public interface ViewResolver {
    2. @Nullable
    3. //resolveViewName 解析视图
    4. View resolveViewName(String viewName, Locale locale) throws Exception;
    5. }

    resolveViewName 

    1. @Nullable
    2. public View resolveViewName(String viewName, Locale locale) throws Exception {
    3. RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
    4. Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
    5. List requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
    6. if (requestedMediaTypes != null) {
    7. //getCandidateViews 获取候选视图
    8. List candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
    9. //getBestView 获取最好的视图
    10. View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
    11. if (bestView != null) {
    12. return bestView;
    13. }
    14. }
    15. String mediaTypeInfo = this.logger.isDebugEnabled() && requestedMediaTypes != null ? " given " + requestedMediaTypes.toString() : "";
    16. if (this.useNotAcceptableStatusCode) {
    17. if (this.logger.isDebugEnabled()) {
    18. this.logger.debug("Using 406 NOT_ACCEPTABLE" + mediaTypeInfo);
    19. }
    20. return NOT_ACCEPTABLE_VIEW;
    21. } else {
    22. this.logger.debug("View remains unresolved" + mediaTypeInfo);
    23. return null;
    24. }
    25. }

    getCandidateViews 

    1. private List getCandidateViews(String viewName, Locale locale, List requestedMediaTypes) throws Exception {
    2. List candidateViews = new ArrayList();
    3. if (this.viewResolvers != null) {
    4. Assert.state(this.contentNegotiationManager != null, "No ContentNegotiationManager set");
    5. Iterator var5 = this.viewResolvers.iterator();
    6. while(var5.hasNext()) {
    7. ViewResolver viewResolver = (ViewResolver)var5.next();
    8. View view = viewResolver.resolveViewName(viewName, locale);
    9. if (view != null) {
    10. candidateViews.add(view);
    11. }
    12. Iterator var8 = requestedMediaTypes.iterator();
    13. while(var8.hasNext()) {
    14. MediaType requestedMediaType = (MediaType)var8.next();
    15. List extensions = this.contentNegotiationManager.resolveFileExtensions(requestedMediaType);
    16. Iterator var11 = extensions.iterator();
    17. while(var11.hasNext()) {
    18. String extension = (String)var11.next();
    19. String viewNameWithExtension = viewName + '.' + extension;
    20. view = viewResolver.resolveViewName(viewNameWithExtension, locale);
    21. if (view != null) {
    22. candidateViews.add(view);
    23. }
    24. }
    25. }
    26. }
    27. }
    28. if (!CollectionUtils.isEmpty(this.defaultViews)) {
    29. candidateViews.addAll(this.defaultViews);
    30. }
    31. return candidateViews;
    32. }
    1. //全面扩展SpringMVC
    2. //如果想要diy一些定制化的功能,只需要写这个组件
    3. // 然后将它交给springboot,springboot就睡帮助我们进行自动装配
    4. @Configuration
    5. public class MyMvcConfig implements WebMvcConfigurer {
    6. //ContentNegotiatingViewResolver 实现了视图解析器的类,就可以把它看做视图解析器
    7. @Bean
    8. public ViewResolver myViewResolver(){
    9. return new MyViewResolver();
    10. }
    11. //
    12. public static class MyViewResolver implements ViewResolver{
    13. @Override
    14. public View resolveViewName(String viewName, Locale locale) throws IOException{
    15. return null;
    16. }
    17. }
    18. }

    三、Formatter 转换器和格式化器

    1. @Bean
    2. @Override
    3. public FormattingConversionService mvcConversionService() {
    4. Format format = this.mvcProperties.getFormat();
    5. WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
    6. .dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
    7. addFormatters(conversionService);
    8. return conversionService;
    9. }
    1. public DateTimeFormatters dateFormat(String pattern) {
    2. if (isIso(pattern)) {
    3. this.dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
    4. this.datePattern = "yyyy-MM-dd";
    5. }
    6. else {
    7. this.dateFormatter = formatter(pattern);
    8. this.datePattern = pattern;
    9. }
    10. return this;
    11. }

    四、修改SpringBoot的默认配置

    SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;

    如果有些组件可以存在多个,例如视图解析器,可以将用户配置的和默认的组合起来使用

    五、扩展使用SpringMVC

    编写类型为WebMvcConfigurer的@Configuration注解类

    且不能标注@EnableWebMvc注解;

    需要自己写一个;

    新建一个包:config,创建类MyMvcConfig;

    ⚪实现视图跳转

    1. @Configuration
    2. public class MyMvcConfig implements WebMvcConfigurer {
    3. //视图跳转
    4. @Override
    5. public void addViewControllers(ViewControllerRegistry registry){
    6. registry.addViewController("/zhang").setViewName("test");
    7. }
    8. }

  • 相关阅读:
    【趣味随笔】盘点国内外做双足机器人的公司
    【AI语音】华为EC6110M、Q21AQ、Q21C部分EC6110T、EC6110U_海思3798MV310_通刷_卡刷固件
    Hive (八) --------- 函数
    7.20 Codeforces Round #763 (Div. 2) C(二分) D(数学期望)背包+树形dp复习
    查找2个dom节点的最近的共同父元素
    OpenGL之坐标系以及单位
    EluxJS-让你像切蛋糕一样拆解前端巨石应用
    为实验室运维提供安全、智能、节能整体解决方案的易云维®实验室智能化管理平台
    网络安全项目简介
    nginx 部署前端资源的最佳方案
  • 原文地址:https://blog.csdn.net/m0_52982868/article/details/126529454