栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

【Spring Boot】web开发相关源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring Boot】web开发相关源码分析

一、MVC自动配置 1、默认支持的功能

Spring Boot为Spring MVC提供了自动配置,默认支持以下功能

  • ContentNegotiatingViewResolver和BeanNameViewResolver视图解析器
  • 支持静态资源,包括webjars
  • 转换器的自动注册、自定义转换器GenericConverter与格式化
  • 支持http消息转换(请求与响应)
  • MessageCodesResolver错误消息
  • 首页映射
  • 图标自定义
  • 自动使用ConfigurableWebBindingInitializer,博主百度了一下,它的主要作用就是初始化WebDataBinder,将请求的参数转化为对应的JavaBean,并且会结合类型、格式转换等API一起使用
2、静态资源与首页相关源码解析

SpringBoot启动时会默认加载 xxxAutoConfiguration 类(自动配置类),SpringMVC功能的自动配置类为 WebMvcAutoConfiguration

@AutoConfiguration(
    after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
public class WebMvcAutoConfiguration {
	...
}

然后我们可以看到他有一个静态内部类WebMvcAutoConfigurationAdapter,可以看到这是一个配置类

@Configuration(
    proxyBeanMethods = false
)
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
// 将配置文件的相关属性和括号中的两个类进行了绑定,然后注册到容器中。WebMvcProperties和spring.mvc开头的配置、WebProperties和spring.web开头的配置
@EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
	...
}

然后我们发现,这个配置类只有一个有参构造器,在这种情况下,我们默认有参构造器所有参数的值都会从容器中获取

// 这里的WebProperties 和WebMvcProperties都在上面和配置进行绑定过了,如果我们没有配置该配置项,那就去类中取默认配置的值
// ListableBeanFactory beanFactory Spring的beanFactory
// 其他的可以自己去了解下,博主这里没有特地去搜了
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider messageConvertersProvider, ObjectProvider resourceHandlerRegistrationCustomizerProvider, ObjectProvider dispatcherServletPath, ObjectProvider> servletRegistrations) {
	this.resourceProperties = webProperties.getResources();
	this.mvcProperties = mvcProperties;
	this.beanFactory = beanFactory;
	this.messageConvertersProvider = messageConvertersProvider;
	this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
	this.dispatcherServletPath = dispatcherServletPath;
	this.servletRegistrations = servletRegistrations;
	this.mvcProperties.checkConfiguration();
}

那么我们的静态资源映射以及webjars都是在哪里进行配置的呢,我们往下看找到一个方法

public void addResourceHandlers(ResourceHandlerRegistry registry) {
	// 判断这个isAddMappings属性是否为false,默认值是true,如果我们在yaml文件或者properties中改为false,那么就会进这个条件语句,后面的静态资源路径以及webjars都不会生效了
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
    } else {
    	// webjars的规则
        this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
        // 默认静态资源地址的处理规则
        this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
            registration.addResourceLocations(this.resourceProperties.getStaticLocations());
            if (this.servletContext != null) {
                ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                registration.addResourceLocations(new Resource[]{resource});
            }

        });
    }
}

那我们欢迎页是在哪里配置的呢?
我们发现,在这个WebMvcAutoConfiguration下面还有一个静态内部类EnableWebMvcConfiguration,它也是一个配置类

这里面有一个方法welcomePageHandlerMapping()
HandlerMapping(处理映射器):根据URL找到对应的处理器

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
    return welcomePageHandlerMapping;
}

点进WelcomePageHandlerMapping的构造方法可以看到,它的逻辑大体上为,如果welcomePage不等于null,而且staticPathPattern是默认的/**,就会去我们的静态资源文件夹找index.html,否则就去找有没有能处理/index接口的映射器

这里的staticPathPattern和spring.mvc.static-path-pattern是绑定在一起的

WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
    if (welcomePage != null && "/**".equals(staticPathPattern)) {
        logger.info("Adding welcome page: " + welcomePage);
        this.setRootViewName("forward:index.html");
    } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
        logger.info("Adding welcome page template: index");
        this.setRootViewName("index");
    }

}
3、未完待续,明日更新
转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1039478.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号