本文的目的是介绍无法使用SpringBoot+GORM+Gradle设置NamingStrategy的详细情况,特别关注无法使用com.mysql.jdbc.driver的相关信息。我们将通过专业的研
本文的目的是介绍无法使用Spring Boot + GORM + Gradle设置NamingStrategy的详细情况,特别关注无法使用com.mysql.jdbc.driver的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解无法使用Spring Boot + GORM + Gradle设置NamingStrategy的机会,同时也不会遗漏关于001-快速搭建Spring web应用【springboot 2.0.4】-gradle、springboot的启动过程分析、gradle多模块构建、ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2...、com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy的实例源码、com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy的实例源码的知识。
本文目录一览:- 无法使用Spring Boot + GORM + Gradle设置NamingStrategy(无法使用com.mysql.jdbc.driver)
- 001-快速搭建Spring web应用【springboot 2.0.4】-gradle、springboot的启动过程分析、gradle多模块构建
- ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2...
- com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy的实例源码
- com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy的实例源码
无法使用Spring Boot + GORM + Gradle设置NamingStrategy(无法使用com.mysql.jdbc.driver)
我们正在使用带有GORM和Gradle的Spring Boot启动一个新项目。我已经能够为hibernate配置大多数属性,但是到目前为止,我还没有找到设置
命名策略 的正确方法。
尝试次数
我尝试在 application.properties中 设置各种属性,并添加文件 hibernate.properties
。我们正在使用自动配置,我看到在 HibernateGormAutoConfiguration 中发现了道具并添加了道具。
我也做了一些尝试来创建实体管理器和会话工厂bean,但是没有运气。
application.properties中的示例 (尝试所有排列):
spring.hibernate.hbm2ddl.auto=none # this works!!# from now on none works# I tried all permutations with combinations of# *.hibernate[.ejb].* and *.naming_strategy/naming-strategyspring.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.hibernate.ejb.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.jpa.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.properties.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.jpa.properties.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.gorm.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyspring.gorm.properties.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategygorm.hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategy
src / main / resources / hibernate.properties中的示例:
hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategyhibernate.ejb.namingStrategy=org.hibernate.cfg.DefaultNamingStrategy
启动应用程序并尝试加载实体时的日志记录和stacktrace:
2014-11-03 10:12:04.381 INFO 81729 --- [ main] org.hibernate.cfg.Environment : HHH000205: Loaded properties from ... resource hibernate.properties: {hibernate.ejb.namingStrategy=org.hibernate.cfg.DefaultNamingStrategy, hibernate.namingStrategy=org.hibernate.cfg.DefaultNamingStrategy, hibernate.bytecode.use_reflection_optimizer=false}2014-11-03 10:09:28.825 WARN 81619 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 207, SQLState: 42S222014-11-03 10:09:28.825 ERROR 81619 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid column name ''origin_marking''.2014-11-03 10:09:28.839 ERROR 81619 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[jerseyServlet] : Servlet.service() for servlet [jerseyServlet] in context with path [] threw exception [org.springframework.jdbc.BadSqlGrammarException: Hibernate operation: could not extract ResultSet; bad SQL grammar [n/a]; nested exception is java.sql.SQLException: Invalid column name ''origin_marking''.] with root cause java.sql.SQLException: Invalid column name ''origin_marking''. at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372)
代码示例
不幸的是,在每个字段上覆盖字段名称不是可行的解决方案:
static mapping = { columns { originMarking column: ''originMarking'' }}
构建文件的节选如下所示:
.. // main build filebuildscript { repositories { jcenter() maven { url "http://repo.spring.io/milestone" } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.0.M2") classpath ''org.springframework:springloaded:1.2.0.RELEASE'' }}..apply plugin: ''spring-boot''.... // domain build filejar.baseName = ''domain''dependencies { compile "org.grails:gorm-hibernate4-spring-boot:1.1.0.RELEASE", "joda-time:joda-time:2.5", ''org.jadira.usertype:usertype.jodatime:2.0.1'', "commons-dbcp:commons-dbcp:1.4", "net.sourceforge.jtds:jtds:1.2.7" runtime "com.h2database:h2"}.... // api build fileapply plugin: ''spring-boot''jar.baseName = ''api''dependencies { compile project('':domain'') compile "org.springframework.boot:spring-boot-starter-jersey" ..}
任何帮助将不胜感激!
答案1
小编典典Grails确实会使用该spring.hibernate.naming_strategy
设置,但不会以您期望的方式使用它,并且保留了默认的命名策略。我不确定是什么原因。您可能想提出一个问题,与Grails团队讨论。
同时,可以通过调用来configureNamingStrategy
以编程方式配置默认命名策略AbstractGrailsDomainBinder
。例如:
@EnableAutoConfigurationclass Application { static void main(String[] args) { AbstractGrailsDomainBinder.configureNamingStrategy(''DEFAULT'', DefaultNamingStrategy) SpringApplication.run Application, args }}
001-快速搭建Spring web应用【springboot 2.0.4】-gradle、springboot的启动过程分析、gradle多模块构建
一、概述
学习《精通Spring MVC4》书籍笔记
二、笔记
1、快速构建Spring starter web项目几种方式
1》使用Spring Tool Suite生成Starter代码;sts是集成的eclipse工具,下载地址:https://spring.io/tools3/sts/all
2》使用 idea 14版本以上
3》使用站点:https://start.spring.io/ 配置后下载zip文件
4》使用https://start.spring.io/站点的curl命令
2、其他 gradle或maven,spring 4 ,java8 lambda,heroku,git
git:需要安装,git交互式教程:http://try.github.io/;git交互学习界面:https://learngitbranching.js.org/
gradle构建:Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。
mac上使用:参看官网即可:https://gradle.org/
1、安装java,检测java:javas -version
2、支持手动安装和包安装(推荐),手动的参看官网
brew install gradle
注:brew是一个软件包管理工具,类似于centos下的yum或者ubuntu下的apt-get,非常方便,免去了自己手动编译安装的不便
安装brew:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
查看版本:gradle -v;配置idea路径:/usr/local/Cellar/gradle/5.1/libexec
3、可以基于上面的第4创建一个springboot项目,尝试使用gradle
gradle的dependencies
Configuration name | Role | Consumable? | Resolvable? | Description |
---|---|---|---|---|
|
Declaring API dependencies |
no |
no |
This is where you should declare dependencies which are transitively exported to consumers, for compile. |
|
Declaring implementation dependencies |
no |
no |
This is where you should declare dependencies which are purely internal and not meant to be exposed to consumers. 在这里,您应该声明纯粹内部的依赖关系,而不是要向消费者公开。 |
|
Declaring compile only dependencies |
yes |
yes |
This is where you should declare dependencies which are only required at compile time, but should not leak into the runtime. This typically includes dependencies which are shaded when found at runtime. 这是您应该声明仅在编译时需要的依赖项,但不应泄漏到运行时。这通常包括在运行时找到时被着色的依赖项。 |
|
Declaring runtime dependencies |
no |
no |
This is where you should declare dependencies which are only required at runtime, and not at compile time. |
|
Test dependencies |
no |
no |
This is where you should declare dependencies which are used to compile tests. |
|
Declaring test compile only dependencies |
yes |
yes |
This is where you should declare dependencies which are only required at test compile time, but should not leak into the runtime. This typically includes dependencies which are shaded when found at runtime. |
|
Declaring test runtime dependencies |
no |
no |
This is where you should declare dependencies which are only required at test runtime, and not at test compile time. |
参看地址:https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation
3、spring boot
3.1、spring mvc初始步骤
1》初始化Spring MVC的DIspatchServlet;
2》搭建转码过滤器,保证客户端请求进行正确地转码;
3》搭建视图解析器(View resolver),告诉Spring去哪里查找视图,以及他们是使用哪种前端模板编写的(jsp、thymeleaf、freemarker模板等)
4》配置静态资源的位置(css,js);
5》配置所支持的地域以及资源bundle;
6》配置multipart解析器,保证文件上传能够正常工作;
7》将tomcat或jetty包含进来,从而能够在we服务器上运行我们的应用
8》建立错误页面
spring boot主要是基于约定,默认会在项目中使用上述约定。
3.2、分发器和multipart配置
在application.properties中添加:
debug=true
查看在springboot启动时候究竟发生了什么


============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
CodecsAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.codec.CodecConfigurer''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
CodecsAutoConfiguration.JacksonCodecConfiguration matched:
- @ConditionalOnClass found required class ''com.fasterxml.jackson.databind.ObjectMapper''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
CodecsAutoConfiguration.JacksonCodecConfiguration#jacksonCodecCustomizer matched:
- @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean ''jacksonObjectMapper'' (OnBeanCondition)
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.web.servlet.DispatcherServlet''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
- @ConditionalOnClass found required class ''javax.servlet.ServletRegistration''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration matched:
- @ConditionalOnClass found required class ''javax.servlet.ServletRegistration''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- DispatcherServlet Registration did not find servlet registration bean (DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition)
DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration#dispatcherServletRegistration matched:
- @ConditionalOnBean (names: dispatcherServlet; types: org.springframework.web.servlet.DispatcherServlet; SearchStrategy: all) found bean ''dispatcherServlet'' (OnBeanCondition)
EmbeddedWebServerFactoryCustomizerAutoConfiguration.TomcatWebServerFactoryCustomizerConfiguration matched:
- @ConditionalOnClass found required classes ''org.apache.catalina.startup.Tomcat'', ''org.apache.coyote.UpgradeProtocol''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
ErrorMvcAutoConfiguration matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''org.springframework.web.servlet.DispatcherServlet''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
ErrorMvcAutoConfiguration#basicErrorController matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.web.servlet.error.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)
ErrorMvcAutoConfiguration#errorAttributes matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.web.servlet.error.ErrorAttributes; SearchStrategy: current) did not find any beans (OnBeanCondition)
ErrorMvcAutoConfiguration.DefaultErrorViewResolverConfiguration#conventionErrorViewResolver matched:
- @ConditionalOnBean (types: org.springframework.web.servlet.DispatcherServlet; SearchStrategy: all) found bean ''dispatcherServlet''; @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.servlet.error.DefaultErrorViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration matched:
- @ConditionalOnProperty (server.error.whitelabel.enabled) matched (OnPropertyCondition)
- ErrorTemplate Missing did not find error template view (ErrorMvcAutoConfiguration.ErrorTemplateMissingCondition)
ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration#beanNameViewResolver matched:
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.BeanNameViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration#defaultErrorView matched:
- @ConditionalOnMissingBean (names: error; SearchStrategy: all) did not find any beans (OnBeanCondition)
GenericCacheConfiguration matched:
- Cache org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration automatic cache type (CacheCondition)
HttpEncodingAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.web.filter.CharacterEncodingFilter''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
- @ConditionalOnProperty (spring.http.encoding.enabled) matched (OnPropertyCondition)
HttpEncodingAutoConfiguration#characterEncodingFilter matched:
- @ConditionalOnMissingBean (types: org.springframework.web.filter.CharacterEncodingFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)
HttpMessageConvertersAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.converter.HttpMessageConverter''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
HttpMessageConvertersAutoConfiguration#messageConverters matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.http.HttpMessageConverters; SearchStrategy: all) did not find any beans (OnBeanCondition)
HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.converter.StringHttpMessageConverter''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration#stringHttpMessageConverter matched:
- @ConditionalOnMissingBean (types: org.springframework.http.converter.StringHttpMessageConverter; SearchStrategy: all) did not find any beans (OnBeanCondition)
JacksonAutoConfiguration matched:
- @ConditionalOnClass found required class ''com.fasterxml.jackson.databind.ObjectMapper''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
JacksonAutoConfiguration.Jackson2ObjectMapperBuilderCustomizerConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.converter.json.Jackson2ObjectMapperBuilder''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.converter.json.Jackson2ObjectMapperBuilder''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder matched:
- @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition)
JacksonAutoConfiguration.JacksonObjectMapperConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.http.converter.json.Jackson2ObjectMapperBuilder''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper matched:
- @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)
JacksonAutoConfiguration.ParameterNamesModuleConfiguration matched:
- @ConditionalOnClass found required class ''com.fasterxml.jackson.module.paramnames.ParameterNamesModule''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
JacksonAutoConfiguration.ParameterNamesModuleConfiguration#parameterNamesModule matched:
- @ConditionalOnMissingBean (types: com.fasterxml.jackson.module.paramnames.ParameterNamesModule; SearchStrategy: all) did not find any beans (OnBeanCondition)
JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration matched:
- @ConditionalOnClass found required class ''com.fasterxml.jackson.databind.ObjectMapper''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnProperty (spring.http.converters.preferred-json-mapper=jackson) matched (OnPropertyCondition)
- @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean ''jacksonObjectMapper'' (OnBeanCondition)
JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter matched:
- @ConditionalOnMissingBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) did not find any beans (OnBeanCondition)
JmxAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.jmx.export.MBeanExporter''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnProperty (spring.jmx.enabled=true) matched (OnPropertyCondition)
JmxAutoConfiguration#mbeanExporter matched:
- @ConditionalOnMissingBean (types: org.springframework.jmx.export.MBeanExporter; SearchStrategy: current) did not find any beans (OnBeanCondition)
JmxAutoConfiguration#mbeanServer matched:
- @ConditionalOnMissingBean (types: javax.management.MBeanServer; SearchStrategy: all) did not find any beans (OnBeanCondition)
JmxAutoConfiguration#objectNamingStrategy matched:
- @ConditionalOnMissingBean (types: org.springframework.jmx.export.naming.ObjectNamingStrategy; SearchStrategy: current) did not find any beans (OnBeanCondition)
MultipartAutoConfiguration matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''org.springframework.web.multipart.support.StandardServletMultipartResolver'', ''javax.servlet.MultipartConfigElement''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
- @ConditionalOnProperty (spring.servlet.multipart.enabled) matched (OnPropertyCondition)
MultipartAutoConfiguration#multipartConfigElement matched:
- @ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement,org.springframework.web.multipart.commons.CommonsMultipartResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
MultipartAutoConfiguration#multipartResolver matched:
- @ConditionalOnMissingBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
NoOpCacheConfiguration matched:
- Cache org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration automatic cache type (CacheCondition)
PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer matched:
- @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) did not find any beans (OnBeanCondition)
RestTemplateAutoConfiguration matched:
- @ConditionalOnClass found required class ''org.springframework.web.client.RestTemplate''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
RestTemplateAutoConfiguration#restTemplateBuilder matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.web.client.RestTemplateBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition)
ServletWebServerFactoryAutoConfiguration matched:
- @ConditionalOnClass found required class ''javax.servlet.ServletRequest''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
ServletWebServerFactoryAutoConfiguration#tomcatServletWebServerFactoryCustomizer matched:
- @ConditionalOnClass found required class ''org.apache.catalina.startup.Tomcat''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
ServletWebServerFactoryConfiguration.EmbeddedTomcat matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''org.apache.catalina.startup.Tomcat'', ''org.apache.coyote.UpgradeProtocol''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnMissingBean (types: org.springframework.boot.web.servlet.server.ServletWebServerFactory; SearchStrategy: current) did not find any beans (OnBeanCondition)
SimpleCacheConfiguration matched:
- Cache org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration automatic cache type (CacheCondition)
SpringApplicationAdminJmxAutoConfiguration matched:
- @ConditionalOnProperty (spring.application.admin.enabled=true) matched (OnPropertyCondition)
SpringApplicationAdminJmxAutoConfiguration#springApplicationAdminRegistrar matched:
- @ConditionalOnMissingBean (types: org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar; SearchStrategy: all) did not find any beans (OnBeanCondition)
ValidationAutoConfiguration matched:
- @ConditionalOnClass found required class ''javax.validation.executable.ExecutableValidator''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- @ConditionalOnResource found location classpath:META-INF/services/javax.validation.spi.ValidationProvider (OnResourceCondition)
ValidationAutoConfiguration#defaultValidator matched:
- @ConditionalOnMissingBean (types: javax.validation.Validator; SearchStrategy: all) did not find any beans (OnBeanCondition)
ValidationAutoConfiguration#methodValidationPostProcessor matched:
- @ConditionalOnMissingBean (types: org.springframework.validation.beanvalidation.MethodValidationPostProcessor; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''org.springframework.web.servlet.DispatcherServlet'', ''org.springframework.web.servlet.config.annotation.WebMvcConfigurer''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration#hiddenHttpMethodFilter matched:
- @ConditionalOnMissingBean (types: org.springframework.web.filter.HiddenHttpMethodFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration#httpPutFormContentFilter matched:
- @ConditionalOnProperty (spring.mvc.formcontent.putfilter.enabled) matched (OnPropertyCondition)
- @ConditionalOnMissingBean (types: org.springframework.web.filter.HttpPutFormContentFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#defaultViewResolver matched:
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.InternalResourceViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#requestContextFilter matched:
- @ConditionalOnMissingBean (types: org.springframework.web.context.request.RequestContextListener,org.springframework.web.filter.RequestContextFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#viewResolver matched:
- @ConditionalOnBean (types: org.springframework.web.servlet.ViewResolver; SearchStrategy: all) found beans ''defaultViewResolver'', ''beanNameViewResolver'', ''mvcViewResolver''; @ConditionalOnMissingBean (names: viewResolver; types: org.springframework.web.servlet.view.ContentNegotiatingViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.FaviconConfiguration matched:
- @ConditionalOnProperty (spring.mvc.favicon.enabled) matched (OnPropertyCondition)
WebSocketServletAutoConfiguration matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''javax.websocket.server.ServerContainer''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment (OnWebApplicationCondition)
WebSocketServletAutoConfiguration.TomcatWebSocketConfiguration matched:
- @ConditionalOnClass found required classes ''org.apache.catalina.startup.Tomcat'', ''org.apache.tomcat.websocket.server.WsSci''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
WebSocketServletAutoConfiguration.TomcatWebSocketConfiguration#websocketContainerCustomizer matched:
- @ConditionalOnMissingBean (names: websocketServletWebServerCustomizer; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.jms.ConnectionFactory'', ''org.apache.activemq.ActiveMQConnectionFactory'' (OnClassCondition)
AopAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.aspectj.lang.annotation.Aspect'', ''org.aspectj.lang.reflect.Advice'', ''org.aspectj.weaver.AnnotatedElement'' (OnClassCondition)
ArtemisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.jms.ConnectionFactory'', ''org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory'' (OnClassCondition)
BatchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.batch.core.launch.JobLauncher'', ''org.springframework.jdbc.core.JdbcOperations'' (OnClassCondition)
CacheAutoConfiguration:
Did not match:
- @ConditionalOnBean (types: org.springframework.cache.interceptor.CacheAspectSupport; SearchStrategy: all) did not find any beans of type org.springframework.cache.interceptor.CacheAspectSupport (OnBeanCondition)
Matched:
- @ConditionalOnClass found required class ''org.springframework.cache.CacheManager''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
CacheAutoConfiguration.CacheManagerJpaDependencyConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'' (OnClassCondition)
- Ancestor org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration did not match (ConditionEvaluationReport.AncestorsMatchedCondition)
CaffeineCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.github.benmanes.caffeine.cache.Caffeine'', ''org.springframework.cache.caffeine.CaffeineCacheManager'' (OnClassCondition)
CassandraAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.datastax.driver.core.Cluster'' (OnClassCondition)
CassandraDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.datastax.driver.core.Cluster'', ''org.springframework.data.cassandra.core.CassandraAdminOperations'' (OnClassCondition)
CassandraReactiveDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.datastax.driver.core.Cluster'', ''org.springframework.data.cassandra.core.ReactiveCassandraTemplate'', ''reactor.core.publisher.Flux'' (OnClassCondition)
CassandraReactiveRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.data.cassandra.ReactiveSession'', ''org.springframework.data.cassandra.repository.ReactiveCassandraRepository'' (OnClassCondition)
CassandraRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.datastax.driver.core.Session'', ''org.springframework.data.cassandra.repository.CassandraRepository'' (OnClassCondition)
CloudAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.cloud.config.java.CloudScanConfiguration'' (OnClassCondition)
CouchbaseAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.CouchbaseBucket'', ''com.couchbase.client.java.Cluster'' (OnClassCondition)
CouchbaseCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.Bucket'', ''com.couchbase.client.spring.cache.CouchbaseCacheManager'' (OnClassCondition)
CouchbaseDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.Bucket'', ''org.springframework.data.couchbase.repository.CouchbaseRepository'' (OnClassCondition)
CouchbaseReactiveDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.Bucket'', ''org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository'', ''reactor.core.publisher.Flux'' (OnClassCondition)
CouchbaseReactiveRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.Bucket'', ''org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository'', ''reactor.core.publisher.Flux'' (OnClassCondition)
CouchbaseRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.couchbase.client.java.Bucket'', ''org.springframework.data.couchbase.repository.CouchbaseRepository'' (OnClassCondition)
DataSourceAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'' (OnClassCondition)
DataSourceTransactionManagerAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.jdbc.core.JdbcTemplate'', ''org.springframework.transaction.PlatformTransactionManager'' (OnClassCondition)
DispatcherServletAutoConfiguration.DispatcherServletConfiguration#multipartResolver:
Did not match:
- @ConditionalOnBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) did not find any beans of type org.springframework.web.multipart.MultipartResolver (OnBeanCondition)
EhCacheCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''net.sf.ehcache.Cache'', ''org.springframework.cache.ehcache.EhCacheCacheManager'' (OnClassCondition)
ElasticsearchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.elasticsearch.client.Client'', ''org.springframework.data.elasticsearch.client.TransportClientFactoryBean'' (OnClassCondition)
ElasticsearchDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.elasticsearch.client.Client'', ''org.springframework.data.elasticsearch.core.ElasticsearchTemplate'' (OnClassCondition)
ElasticsearchRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.elasticsearch.client.Client'', ''org.springframework.data.elasticsearch.repository.ElasticsearchRepository'' (OnClassCondition)
EmbeddedLdapAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.unboundid.ldap.listener.InMemoryDirectoryServer'' (OnClassCondition)
EmbeddedMongoAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.mongodb.MongoClient'', ''de.flapdoodle.embed.mongo.MongodStarter'' (OnClassCondition)
EmbeddedWebServerFactoryCustomizerAutoConfiguration.JettyWebServerFactoryCustomizerConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.eclipse.jetty.server.Server'', ''org.eclipse.jetty.util.Loader'', ''org.eclipse.jetty.webapp.WebAppContext'' (OnClassCondition)
EmbeddedWebServerFactoryCustomizerAutoConfiguration.UndertowWebServerFactoryCustomizerConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''io.undertow.Undertow'', ''org.xnio.SslClientAuthMode'' (OnClassCondition)
ErrorWebFluxAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.web.reactive.config.WebFluxConfigurer'' (OnClassCondition)
FlywayAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.flywaydb.core.Flyway'' (OnClassCondition)
FreeMarkerAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''freemarker.template.Configuration'', ''org.springframework.ui.freemarker.FreeMarkerConfigurationFactory'' (OnClassCondition)
GroovyTemplateAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''groovy.text.markup.MarkupTemplateEngine'' (OnClassCondition)
GsonAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.google.gson.Gson'' (OnClassCondition)
GsonHttpMessageConvertersConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.google.gson.Gson'' (OnClassCondition)
H2ConsoleAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.h2.server.web.WebServlet'' (OnClassCondition)
HazelcastAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.hazelcast.core.HazelcastInstance'' (OnClassCondition)
HazelcastCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.hazelcast.core.HazelcastInstance'', ''com.hazelcast.spring.cache.HazelcastCacheManager'' (OnClassCondition)
HazelcastJpaDependencyAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.hazelcast.core.HazelcastInstance'', ''org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'' (OnClassCondition)
HibernateJpaAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'', ''javax.persistence.EntityManager'' (OnClassCondition)
HttpHandlerAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.web.reactive.DispatcherHandler'' (OnClassCondition)
HypermediaAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.hateoas.Resource'', ''org.springframework.plugin.core.Plugin'' (OnClassCondition)
InfinispanCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.infinispan.spring.provider.SpringEmbeddedCacheManager'' (OnClassCondition)
InfluxDbAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.influxdb.InfluxDB'' (OnClassCondition)
IntegrationAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.integration.config.EnableIntegration'' (OnClassCondition)
JCacheCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.cache.Caching'', ''org.springframework.cache.jcache.JCacheCacheManager'' (OnClassCondition)
JacksonAutoConfiguration.JodaDateTimeJacksonConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.joda.time.DateTime'', ''com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer'', ''com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat'' (OnClassCondition)
JacksonHttpMessageConvertersConfiguration.MappingJackson2XmlHttpMessageConverterConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.fasterxml.jackson.dataformat.xml.XmlMapper'' (OnClassCondition)
JdbcTemplateAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.jdbc.core.JdbcTemplate'' (OnClassCondition)
JerseyAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.glassfish.jersey.server.spring.SpringComponentProvider'' (OnClassCondition)
JestAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''io.searchbox.client.JestClient'' (OnClassCondition)
JmsAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.jms.Message'', ''org.springframework.jms.core.JmsTemplate'' (OnClassCondition)
JndiConnectionFactoryAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.jms.core.JmsTemplate'' (OnClassCondition)
JndiDataSourceAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'' (OnClassCondition)
JooqAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.jooq.DSLContext'' (OnClassCondition)
JpaRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.jpa.repository.JpaRepository'' (OnClassCondition)
JsonbAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''javax.json.bind.Jsonb'' (OnClassCondition)
JsonbHttpMessageConvertersConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''javax.json.bind.Jsonb'' (OnClassCondition)
JtaAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''javax.transaction.Transaction'' (OnClassCondition)
KafkaAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.kafka.core.KafkaTemplate'' (OnClassCondition)
LdapAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.ldap.core.ContextSource'' (OnClassCondition)
LdapDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.ldap.repository.LdapRepository'' (OnClassCondition)
LdapRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.ldap.repository.LdapRepository'' (OnClassCondition)
LiquibaseAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''liquibase.integration.spring.SpringLiquibase'', ''liquibase.change.DatabaseChange'' (OnClassCondition)
MailSenderAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.mail.internet.MimeMessage'', ''org.springframework.mail.MailSender'' (OnClassCondition)
MailSenderValidatorAutoConfiguration:
Did not match:
- @ConditionalOnProperty (spring.mail.test-connection) did not find property ''test-connection'' (OnPropertyCondition)
MessageSourceAutoConfiguration:
Did not match:
- ResourceBundle did not find bundle with basename messages (MessageSourceAutoConfiguration.ResourceBundleCondition)
MongoAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.mongodb.MongoClient'' (OnClassCondition)
MongoDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.mongodb.MongoClient'', ''org.springframework.data.mongodb.core.MongoTemplate'' (OnClassCondition)
MongoReactiveAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.mongodb.reactivestreams.client.MongoClient'' (OnClassCondition)
MongoReactiveDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.mongodb.reactivestreams.client.MongoClient'', ''org.springframework.data.mongodb.core.ReactiveMongoTemplate'' (OnClassCondition)
MongoReactiveRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.mongodb.reactivestreams.client.MongoClient'', ''org.springframework.data.mongodb.repository.ReactiveMongoRepository'' (OnClassCondition)
MongoRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''com.mongodb.MongoClient'', ''org.springframework.data.mongodb.repository.MongoRepository'' (OnClassCondition)
MustacheAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.samskivert.mustache.Mustache'' (OnClassCondition)
Neo4jDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.neo4j.ogm.session.SessionFactory'', ''org.springframework.data.neo4j.transaction.Neo4jTransactionManager'', ''org.springframework.transaction.PlatformTransactionManager'' (OnClassCondition)
Neo4jRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.neo4j.ogm.session.Neo4jSession'', ''org.springframework.data.neo4j.repository.Neo4jRepository'' (OnClassCondition)
OAuth2ClientAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.security.config.annotation.web.configuration.EnableWebSecurity'', ''org.springframework.security.oauth2.client.registration.ClientRegistration'' (OnClassCondition)
PersistenceExceptionTranslationAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor'' (OnClassCondition)
ProjectInfoAutoConfiguration#buildProperties:
Did not match:
- @ConditionalOnResource did not find resource ''${spring.info.build.location:classpath:META-INF/build-info.properties}'' (OnResourceCondition)
ProjectInfoAutoConfiguration#gitProperties:
Did not match:
- GitResource did not find git info at classpath:git.properties (ProjectInfoAutoConfiguration.GitResourceAvailableCondition)
QuartzAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.quartz.Scheduler'', ''org.springframework.scheduling.quartz.SchedulerFactoryBean'', ''org.springframework.transaction.PlatformTransactionManager'' (OnClassCondition)
RabbitAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.amqp.rabbit.core.RabbitTemplate'', ''com.rabbitmq.client.Channel'' (OnClassCondition)
ReactiveUserDetailsServiceAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.security.authentication.ReactiveAuthenticationManager'' (OnClassCondition)
ReactiveWebServerFactoryAutoConfiguration:
Did not match:
- not a reactive web application (OnWebApplicationCondition)
Matched:
- @ConditionalOnClass found required class ''org.springframework.http.ReactiveHttpInputMessage''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
ReactorCoreAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''reactor.core.publisher.Mono'', ''reactor.core.publisher.Flux'' (OnClassCondition)
RedisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.redis.core.RedisOperations'' (OnClassCondition)
RedisCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.redis.connection.RedisConnectionFactory'' (OnClassCondition)
RedisReactiveAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.data.redis.connection.ReactiveRedisConnectionFactory'', ''org.springframework.data.redis.core.ReactiveRedisTemplate'', ''reactor.core.publisher.Flux'' (OnClassCondition)
RedisRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.redis.repository.configuration.EnableRedisRepositories'' (OnClassCondition)
RepositoryRestMvcAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration'' (OnClassCondition)
SecurityAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.security.authentication.DefaultAuthenticationEventPublisher'' (OnClassCondition)
SecurityFilterAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer'', ''org.springframework.security.config.http.SessionCreationPolicy'' (OnClassCondition)
SendGridAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''com.sendgrid.SendGrid'' (OnClassCondition)
ServletWebServerFactoryConfiguration.EmbeddedJetty:
Did not match:
- @ConditionalOnClass did not find required classes ''org.eclipse.jetty.server.Server'', ''org.eclipse.jetty.util.Loader'', ''org.eclipse.jetty.webapp.WebAppContext'' (OnClassCondition)
ServletWebServerFactoryConfiguration.EmbeddedUndertow:
Did not match:
- @ConditionalOnClass did not find required classes ''io.undertow.Undertow'', ''org.xnio.SslClientAuthMode'' (OnClassCondition)
SessionAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.session.Session'' (OnClassCondition)
SolrAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.apache.solr.client.solrj.impl.HttpSolrClient'', ''org.apache.solr.client.solrj.impl.CloudSolrClient'' (OnClassCondition)
SolrRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.apache.solr.client.solrj.SolrClient'', ''org.springframework.data.solr.repository.SolrRepository'' (OnClassCondition)
SpringDataWebAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.data.web.PageableHandlerMethodArgumentResolver'' (OnClassCondition)
ThymeleafAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.thymeleaf.templatemode.TemplateMode'' (OnClassCondition)
TransactionAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.transaction.PlatformTransactionManager'' (OnClassCondition)
UserDetailsServiceAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.security.authentication.AuthenticationManager'' (OnClassCondition)
WebClientAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.web.reactive.function.client.WebClient'' (OnClassCondition)
WebFluxAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.web.reactive.config.WebFluxConfigurer'' (OnClassCondition)
WebFluxSecurityConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity'', ''org.springframework.security.web.server.WebFilterChainProxy'' (OnClassCondition)
WebMvcAutoConfiguration.ResourceChainCustomizerConfiguration:
Did not match:
- @ConditionalOnEnabledResourceChain did not find class org.webjars.WebJarAssetLocator (OnEnabledResourceChainCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#beanNameViewResolver:
Did not match:
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.BeanNameViewResolver; SearchStrategy: all) found beans of type ''org.springframework.web.servlet.view.BeanNameViewResolver'' beanNameViewResolver (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#localeResolver:
Did not match:
- @ConditionalOnProperty (spring.mvc.locale) did not find property ''locale'' (OnPropertyCondition)
WebServicesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.ws.transport.http.MessageDispatcherServlet'' (OnClassCondition)
WebSocketMessagingAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer'' (OnClassCondition)
WebSocketReactiveAutoConfiguration:
Did not match:
- not a reactive web application (OnWebApplicationCondition)
Matched:
- @ConditionalOnClass found required classes ''javax.servlet.Servlet'', ''javax.websocket.server.ServerContainer''; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
WebSocketServletAutoConfiguration.JettyWebSocketConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer'' (OnClassCondition)
WebSocketServletAutoConfiguration.UndertowWebSocketConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ''io.undertow.websockets.jsr.Bootstrap'' (OnClassCondition)
XADataSourceAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes ''javax.transaction.TransactionManager'', ''org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'' (OnClassCondition)
Exclusions:
-----------
None
Unconditional classes:
----------------------
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
此处便是Spring Boot的自动配置报告。主要分为两部分:1、匹配上的(postivie matches),列出了应用中,所有的自动配置;2、没有匹配的(negative matches),没有满足的自动匹配。
查看关键的自动配置:
3.2.1、DispatcherServletAutoConfiguration自动配置
源码:


/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.servlet;
import java.util.Arrays;
import java.util.List;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
/**
* {@link EnableAutoConfiguration Auto-configuration} for the Spring
* {@link DispatcherServlet}. Should work for a standalone application where an embedded
* web server is already present and also for a deployable application using
* {@link SpringBootServletInitializer}.
*
* @author Phillip Webb
* @author Dave Syer
* @author Stephane Nicoll
* @author Brian Clozel
*/
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
@EnableConfigurationProperties(ServerProperties.class)
public class DispatcherServletAutoConfiguration {
/*
* The bean name for a DispatcherServlet that will be mapped to the root URL "/"
*/
public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
/*
* The bean name for a ServletRegistrationBean for the DispatcherServlet "/"
*/
public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";
@Configuration
@Conditional(DefaultDispatcherServletCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
protected static class DispatcherServletConfiguration {
private final WebMvcProperties webMvcProperties;
public DispatcherServletConfiguration(WebMvcProperties webMvcProperties) {
this.webMvcProperties = webMvcProperties;
}
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(
this.webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(
this.webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(
this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
return dispatcherServlet;
}
@Bean
@ConditionalOnBean(MultipartResolver.class)
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
public MultipartResolver multipartResolver(MultipartResolver resolver) {
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;
}
}
@Configuration
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
@Import(DispatcherServletConfiguration.class)
protected static class DispatcherServletRegistrationConfiguration {
private final ServerProperties serverProperties;
private final WebMvcProperties webMvcProperties;
private final MultipartConfigElement multipartConfig;
public DispatcherServletRegistrationConfiguration(
ServerProperties serverProperties, WebMvcProperties webMvcProperties,
ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
this.serverProperties = serverProperties;
this.webMvcProperties = webMvcProperties;
this.multipartConfig = multipartConfigProvider.getIfAvailable();
}
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(
dispatcherServlet, this.serverProperties.getServlet().getPath());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
return registration;
}
}
@Order(Ordered.LOWEST_PRECEDENCE - 10)
private static class DefaultDispatcherServletCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("Default DispatcherServlet");
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
List<String> dispatchServletBeans = Arrays.asList(beanFactory
.getBeanNamesForType(DispatcherServlet.class, false, false));
if (dispatchServletBeans.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
return ConditionOutcome.noMatch(message.found("dispatcher servlet bean")
.items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
}
if (beanFactory.containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
return ConditionOutcome
.noMatch(message.found("non dispatcher servlet bean")
.items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
}
if (dispatchServletBeans.isEmpty()) {
return ConditionOutcome
.match(message.didNotFind("dispatcher servlet beans").atAll());
}
return ConditionOutcome.match(message
.found("dispatcher servlet bean", "dispatcher servlet beans")
.items(Style.QUOTE, dispatchServletBeans)
.append("and none is named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
}
}
@Order(Ordered.LOWEST_PRECEDENCE - 10)
private static class DispatcherServletRegistrationCondition
extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
ConditionOutcome outcome = checkDefaultDispatcherName(beanFactory);
if (!outcome.isMatch()) {
return outcome;
}
return checkServletRegistration(beanFactory);
}
private ConditionOutcome checkDefaultDispatcherName(
ConfigurableListableBeanFactory beanFactory) {
List<String> servlets = Arrays.asList(beanFactory
.getBeanNamesForType(DispatcherServlet.class, false, false));
boolean containsDispatcherBean = beanFactory
.containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
if (containsDispatcherBean
&& !servlets.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {
return ConditionOutcome
.noMatch(startMessage().found("non dispatcher servlet")
.items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME));
}
return ConditionOutcome.match();
}
private ConditionOutcome checkServletRegistration(
ConfigurableListableBeanFactory beanFactory) {
ConditionMessage.Builder message = startMessage();
List<String> registrations = Arrays.asList(beanFactory
.getBeanNamesForType(ServletRegistrationBean.class, false, false));
boolean containsDispatcherRegistrationBean = beanFactory
.containsBean(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
if (registrations.isEmpty()) {
if (containsDispatcherRegistrationBean) {
return ConditionOutcome
.noMatch(message.found("non servlet registration bean").items(
DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
}
return ConditionOutcome
.match(message.didNotFind("servlet registration bean").atAll());
}
if (registrations
.contains(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)) {
return ConditionOutcome.noMatch(message.found("servlet registration bean")
.items(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
}
if (containsDispatcherRegistrationBean) {
return ConditionOutcome
.noMatch(message.found("non servlet registration bean").items(
DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
}
return ConditionOutcome.match(message.found("servlet registration beans")
.items(Style.QUOTE, registrations).append("and none is named "
+ DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME));
}
private ConditionMessage.Builder startMessage() {
return ConditionMessage.forCondition("DispatcherServlet Registration");
}
}
}
是一个典型的Spring boot配置类。
使用了@Configuration注解
通过@AutoConfigureOrder注解来声明优先等级,需要优先进行配置
可以看到具体的分发器DispatcherSerlvet以及multipart解析器的配置
3.3、视图解析器、静态资源以及区域配置
WebMvcAutoConfiguration自动配置
源码


/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.servlet;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import javax.servlet.Servlet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.autoconfigure.validation.ValidatorAdapter;
import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties.Strategy;
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter;
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.ClassUtils;
import org.springframework.validation.DefaultMessageCodesResolver;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.accept.ContentNegotiationStrategy;
import org.springframework.web.accept.PathExtensionContentNegotiationStrategy;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.filter.HttpPutFormContentFilter;
import org.springframework.web.filter.RequestContextFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceChainRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
import org.springframework.web.servlet.resource.GzipResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
* @author Sébastien Deleuze
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Kristine Jetzke
* @author Bruce Brouwer
*/
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = { "/" };
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Bean
@ConditionalOnMissingBean(HttpPutFormContentFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true)
public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
return new OrderedHttpPutFormContentFilter();
}
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@Configuration
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter
implements WebMvcConfigurer, ResourceLoaderAware {
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
private final ResourceProperties resourceProperties;
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
private ResourceLoader resourceLoader;
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
.getIfAvailable();
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
this.messageConvertersProvider.ifAvailable((customConverters) -> converters
.addAll(customConverters.getConverters()));
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
Duration timeout = this.mvcProperties.getAsync().getRequestTimeout();
if (timeout != null) {
configurer.setDefaultTimeout(timeout.toMillis());
}
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(
this.mvcProperties.getPathmatch().isUseSuffixPattern());
configurer.setUseRegisteredSuffixPatternMatch(
this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern());
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
WebMvcProperties.Contentnegotiation contentnegotiation = this.mvcProperties
.getContentnegotiation();
configurer.favorPathExtension(contentnegotiation.isFavorPathExtension());
configurer.favorParameter(contentnegotiation.isFavorParameter());
if (contentnegotiation.getParameterName() != null) {
configurer.parameterName(contentnegotiation.getParameterName());
}
Map<String, MediaType> mediaTypes = this.mvcProperties.getContentnegotiation()
.getMediaTypes();
mediaTypes.forEach(configurer::mediaType);
}
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.mvcProperties.getView().getPrefix());
resolver.setSuffix(this.mvcProperties.getView().getSuffix());
return resolver;
}
@Bean
@ConditionalOnBean(View.class)
@ConditionalOnMissingBean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return resolver;
}
@Bean
@ConditionalOnBean(ViewResolver.class)
@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(
beanFactory.getBean(ContentNegotiationManager.class));
// ContentNegotiatingViewResolver uses all the other view resolvers to locate
// a view so it should have a high precedence
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
return resolver;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
resolver.setMessageCodeFormatter(
this.mvcProperties.getMessageCodesResolverFormat());
return resolver;
}
return null;
}
@Override
public void addFormatters(FormatterRegistry registry) {
for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
registry.addConverter(converter);
}
for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
registry.addConverter(converter);
}
for (Formatter<?> formatter : getBeansOfType(Formatter.class)) {
registry.addFormatter(formatter);
}
}
private <T> Collection<T> getBeansOfType(Class<T> type) {
return this.beanFactory.getBeansOfType(type).values();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache()
.getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
}
private Integer getSeconds(Duration cachePeriod) {
return (cachePeriod != null) ? (int) cachePeriod.getSeconds() : null;
}
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext),
applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
static String[] getResourceLocations(String[] staticLocations) {
String[] locations = new String[staticLocations.length
+ SERVLET_LOCATIONS.length];
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length,
SERVLET_LOCATIONS.length);
return locations;
}
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(
this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml)
.filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
private boolean isReadable(Resource resource) {
try {
return resource.exists() && (resource.getURL() != null);
}
catch (Exception ex) {
return false;
}
}
private void customizeResourceHandlerRegistration(
ResourceHandlerRegistration registration) {
if (this.resourceHandlerRegistrationCustomizer != null) {
this.resourceHandlerRegistrationCustomizer.customize(registration);
}
}
@Bean
@ConditionalOnMissingBean({ RequestContextListener.class,
RequestContextFilter.class })
public static RequestContextFilter requestContextFilter() {
return new OrderedRequestContextFilter();
}
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration implements ResourceLoaderAware {
private final ResourceProperties resourceProperties;
private ResourceLoader resourceLoader;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
}
private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(
this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
.forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
}
}
/**
* Configuration equivalent to {@code @EnableWebMvc}.
*/
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final WebMvcRegistrations mvcRegistrations;
public EnableWebMvcConfiguration(
ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider,
ListableBeanFactory beanFactory) {
this.mvcProperties = mvcPropertiesProvider.getIfAvailable();
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null
|| this.mvcProperties.isIgnoreDefaultModelOnRedirect());
return adapter;
}
@Override
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
if (this.mvcRegistrations != null
&& this.mvcRegistrations.getRequestMappingHandlerAdapter() != null) {
return this.mvcRegistrations.getRequestMappingHandlerAdapter();
}
return super.createRequestMappingHandlerAdapter();
}
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
@Bean
@Override
public FormattingConversionService mvcConversionService() {
WebConversionService conversionService = new WebConversionService(
this.mvcProperties.getDateFormat());
addFormatters(conversionService);
return conversionService;
}
@Bean
@Override
public Validator mvcValidator() {
if (!ClassUtils.isPresent("javax.validation.Validator",
getClass().getClassLoader())) {
return super.mvcValidator();
}
return ValidatorAdapter.get(getApplicationContext(), getValidator());
}
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
if (this.mvcRegistrations != null
&& this.mvcRegistrations.getRequestMappingHandlerMapping() != null) {
return this.mvcRegistrations.getRequestMappingHandlerMapping();
}
return super.createRequestMappingHandlerMapping();
}
@Override
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
return this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
}
catch (NoSuchBeanDefinitionException ex) {
return super.getConfigurableWebBindingInitializer();
}
}
@Override
protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() {
if (this.mvcRegistrations != null && this.mvcRegistrations
.getExceptionHandlerExceptionResolver() != null) {
return this.mvcRegistrations.getExceptionHandlerExceptionResolver();
}
return super.createExceptionHandlerExceptionResolver();
}
@Override
protected void configureHandlerExceptionResolvers(
List<HandlerExceptionResolver> exceptionResolvers) {
super.configureHandlerExceptionResolvers(exceptionResolvers);
if (exceptionResolvers.isEmpty()) {
addDefaultHandlerExceptionResolvers(exceptionResolvers);
}
if (this.mvcProperties.isLogResolvedException()) {
for (HandlerExceptionResolver resolver : exceptionResolvers) {
if (resolver instanceof AbstractHandlerExceptionResolver) {
((AbstractHandlerExceptionResolver) resolver)
.setWarnLogCategory(resolver.getClass().getName());
}
}
}
}
@Bean
@Override
public ContentNegotiationManager mvcContentNegotiationManager() {
ContentNegotiationManager manager = super.mvcContentNegotiationManager();
List<ContentNegotiationStrategy> strategies = manager.getStrategies();
ListIterator<ContentNegotiationStrategy> iterator = strategies.listIterator();
while (iterator.hasNext()) {
ContentNegotiationStrategy strategy = iterator.next();
if (strategy instanceof PathExtensionContentNegotiationStrategy) {
iterator.set(new OptionalPathExtensionContentNegotiationStrategy(
strategy));
}
}
return manager;
}
}
@Configuration
@ConditionalOnEnabledResourceChain
static class ResourceChainCustomizerConfiguration {
@Bean
public ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer() {
return new ResourceChainResourceHandlerRegistrationCustomizer();
}
}
interface ResourceHandlerRegistrationCustomizer {
void customize(ResourceHandlerRegistration registration);
}
private static class ResourceChainResourceHandlerRegistrationCustomizer
implements ResourceHandlerRegistrationCustomizer {
@Autowired
private ResourceProperties resourceProperties = new ResourceProperties();
@Override
public void customize(ResourceHandlerRegistration registration) {
ResourceProperties.Chain properties = this.resourceProperties.getChain();
configureResourceChain(properties,
registration.resourceChain(properties.isCache()));
}
private void configureResourceChain(ResourceProperties.Chain properties,
ResourceChainRegistration chain) {
Strategy strategy = properties.getStrategy();
if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
chain.addResolver(getVersionResourceResolver(strategy));
}
if (properties.isGzipped()) {
chain.addResolver(new GzipResourceResolver());
}
if (properties.isHtmlApplicationCache()) {
chain.addTransformer(new AppCacheManifestTransformer());
}
}
private ResourceResolver getVersionResourceResolver(
ResourceProperties.Strategy properties) {
VersionResourceResolver resolver = new VersionResourceResolver();
if (properties.getFixed().isEnabled()) {
String version = properties.getFixed().getVersion();
String[] paths = properties.getFixed().getPaths();
resolver.addFixedVersionStrategy(version, paths);
}
if (properties.getContent().isEnabled()) {
String[] paths = properties.getContent().getPaths();
resolver.addContentVersionStrategy(paths);
}
return resolver;
}
}
/**
* Decorator to make {@link PathExtensionContentNegotiationStrategy} optional
* depending on a request attribute.
*/
static class OptionalPathExtensionContentNegotiationStrategy
implements ContentNegotiationStrategy {
private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class
.getName() + ".SKIP";
private final ContentNegotiationStrategy delegate;
OptionalPathExtensionContentNegotiationStrategy(
ContentNegotiationStrategy delegate) {
this.delegate = delegate;
}
@Override
public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest)
throws HttpMediaTypeNotAcceptableException {
Object skip = webRequest.getAttribute(SKIP_ATTRIBUTE,
RequestAttributes.SCOPE_REQUEST);
if (skip != null && Boolean.parseBoolean(skip.toString())) {
return MEDIA_TYPE_ALL_LIST;
}
return this.delegate.resolveMediaTypes(webRequest);
}
}
}
视图解析:查看WebMvcAutoConfigurationAdapter中WebMvcProperties属性,可以看到,
spring.mvc.view.prefix=
spring.mvc.view.suffix=
静态资源:以及查看ResourceProperties,可以看到静态资源配置路径,任何一个位置即可。或者使用:spring.resources.static-locations=重新配置
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
静态资源:webjar默认
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache()
.getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
对带有“ewbjar”前缀资源访问将会在类路径中解析,可以使用maven中央仓库预先打包好JavaScript依赖。
WebJars是jar包格式的客户端JavaScript库。
地域管理
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
默认只会处理一个地域,可以自定义:spring.mvc.locale
3.4、错误与转码配置
查看ErrorMvcAutoConfiguration源码


/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.servlet.error;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.Ordered;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.util.HtmlUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} to render errors via an MVC error
* controller.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
// Load before the main WebMvcAutoConfiguration so that the error View is available
@AutoConfigureBefore(WebMvcAutoConfiguration.class)
@EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class })
public class ErrorMvcAutoConfiguration {
private final ServerProperties serverProperties;
private final DispatcherServletPath dispatcherServletPath;
private final List<ErrorViewResolver> errorViewResolvers;
public ErrorMvcAutoConfiguration(ServerProperties serverProperties,
DispatcherServletPath dispatcherServletPath,
ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
this.serverProperties = serverProperties;
this.dispatcherServletPath = dispatcherServletPath;
this.errorViewResolvers = errorViewResolversProvider.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
public DefaultErrorAttributes errorAttributes() {
return new DefaultErrorAttributes(
this.serverProperties.getError().isIncludeException());
}
@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}
@Bean
public ErrorPageCustomizer errorPageCustomizer() {
return new ErrorPageCustomizer(this.serverProperties, this.dispatcherServletPath);
}
@Bean
public static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {
return new PreserveErrorControllerTargetClassPostProcessor();
}
@Configuration
static class DefaultErrorViewResolverConfiguration {
private final ApplicationContext applicationContext;
private final ResourceProperties resourceProperties;
DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext,
ResourceProperties resourceProperties) {
this.applicationContext = applicationContext;
this.resourceProperties = resourceProperties;
}
@Bean
@ConditionalOnBean(DispatcherServlet.class)
@ConditionalOnMissingBean
public DefaultErrorViewResolver conventionErrorViewResolver() {
return new DefaultErrorViewResolver(this.applicationContext,
this.resourceProperties);
}
}
@Configuration
@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)
@Conditional(ErrorTemplateMissingCondition.class)
protected static class WhitelabelErrorViewConfiguration {
private final SpelView defaultErrorView = new SpelView(
"<html><body><h1>Whitelabel Error Page</h1>"
+ "<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>"
+ "<div id=''created''>${timestamp}</div>"
+ "<div>There was an unexpected error (type=${error}, status=${status}).</div>"
+ "<div>${message}</div></body></html>");
@Bean(name = "error")
@ConditionalOnMissingBean(name = "error")
public View defaultErrorView() {
return this.defaultErrorView;
}
// If the user adds @EnableWebMvc then the bean name view resolver from
// WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment.
@Bean
@ConditionalOnMissingBean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return resolver;
}
}
/**
* {@link SpringBootCondition} that matches when no error template view is detected.
*/
private static class ErrorTemplateMissingCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("ErrorTemplate Missing");
TemplateAvailabilityProviders providers = new TemplateAvailabilityProviders(
context.getClassLoader());
TemplateAvailabilityProvider provider = providers.getProvider("error",
context.getEnvironment(), context.getClassLoader(),
context.getResourceLoader());
if (provider != null) {
return ConditionOutcome
.noMatch(message.foundExactly("template from " + provider));
}
return ConditionOutcome
.match(message.didNotFind("error template view").atAll());
}
}
/**
* Simple {@link View} implementation that resolves variables as SpEL expressions.
*/
private static class SpelView implements View {
private static final Log logger = LogFactory.getLog(SpelView.class);
private final NonRecursivePropertyPlaceholderHelper helper;
private final String template;
private volatile Map<String, Expression> expressions;
SpelView(String template) {
this.helper = new NonRecursivePropertyPlaceholderHelper("${", "}");
this.template = template;
}
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
if (response.isCommitted()) {
String message = getMessage(model);
logger.error(message);
return;
}
if (response.getContentType() == null) {
response.setContentType(getContentType());
}
PlaceholderResolver resolver = new ExpressionResolver(getExpressions(),
model);
String result = this.helper.replacePlaceholders(this.template, resolver);
response.getWriter().append(result);
}
private String getMessage(Map<String, ?> model) {
Object path = model.get("path");
String message = "Cannot render error page for request [" + path + "]";
if (model.get("message") != null) {
message += " and exception [" + model.get("message") + "]";
}
message += " as the response has already been committed.";
message += " As a result, the response may have the wrong status code.";
return message;
}
private Map<String, Expression> getExpressions() {
if (this.expressions == null) {
synchronized (this) {
ExpressionCollector expressionCollector = new ExpressionCollector();
this.helper.replacePlaceholders(this.template, expressionCollector);
this.expressions = expressionCollector.getExpressions();
}
}
return this.expressions;
}
}
/**
* {@link PlaceholderResolver} to collect placeholder expressions.
*/
private static class ExpressionCollector implements PlaceholderResolver {
private final SpelExpressionParser parser = new SpelExpressionParser();
private final Map<String, Expression> expressions = new HashMap<>();
@Override
public String resolvePlaceholder(String name) {
this.expressions.put(name, this.parser.parseExpression(name));
return null;
}
public Map<String, Expression> getExpressions() {
return Collections.unmodifiableMap(this.expressions);
}
}
/**
* SpEL based {@link PlaceholderResolver}.
*/
private static class ExpressionResolver implements PlaceholderResolver {
private final Map<String, Expression> expressions;
private final EvaluationContext context;
ExpressionResolver(Map<String, Expression> expressions, Map<String, ?> map) {
this.expressions = expressions;
this.context = getContext(map);
}
private EvaluationContext getContext(Map<String, ?> map) {
return SimpleEvaluationContext.forPropertyAccessors(new MapAccessor())
.withRootObject(map).build();
}
@Override
public String resolvePlaceholder(String placeholderName) {
Expression expression = this.expressions.get(placeholderName);
Object expressionValue = (expression != null)
? expression.getValue(this.context) : null;
return escape(expressionValue);
}
private String escape(Object value) {
return HtmlUtils.htmlEscape((value != null) ? value.toString() : null);
}
}
/**
* {@link WebServerFactoryCustomizer} that configures the server''s error pages.
*/
private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
private final ServerProperties properties;
private final DispatcherServletPath dispatcherServletPath;
protected ErrorPageCustomizer(ServerProperties properties,
DispatcherServletPath dispatcherServletPath) {
this.properties = properties;
this.dispatcherServletPath = dispatcherServletPath;
}
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath
.getRelativePath(this.properties.getError().getPath()));
errorPageRegistry.addErrorPages(errorPage);
}
@Override
public int getOrder() {
return 0;
}
}
/**
* {@link BeanFactoryPostProcessor} to ensure that the target class of ErrorController
* MVC beans are preserved when using AOP.
*/
static class PreserveErrorControllerTargetClassPostProcessor
implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
String[] errorControllerBeans = beanFactory
.getBeanNamesForType(ErrorController.class, false, false);
for (String errorControllerBean : errorControllerBeans) {
try {
beanFactory.getBeanDefinition(errorControllerBean).setAttribute(
AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
}
catch (Throwable ex) {
// Ignore
}
}
}
}
}
定义了一个Bean,即DefaultErrorAttributes,他通过特定的属性暴露了有用的错误信息,这些属性包括状态、错误码和相关的栈跟踪信息
定义了一个BasicErrorController的bean,负责展示错误页。
允许我们将spring boot的whitelabel错误页设置为无效,server.error.whitelabel.enabled=false
还可以以借助模板引擎提供自己的错误页面。他的名字是error.html,ErrorTemplateMissingCondition条件会对此进行检查。
转码:HttpEncodingAutoConfiguration,他是通过Spring的CharacterEncodingFilter类实现,通过spring.http.encoding.charset=UTF-8;配置。如果禁用:spring.http.encoding.enabled=false
3.5、嵌入式Servlet容器配置
查看:EmbeddedWebServerFactoryCustomizerAutoConfiguration代码:


/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.embedded;
import io.undertow.Undertow;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.UpgradeProtocol;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.xnio.SslClientAuthMode;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
* {@link EnableAutoConfiguration Auto-configuration} for embedded servlet and reactive
* web servers customizations.
*
* @author Phillip Webb
* @since 2.0.0
*/
@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
public static class TomcatWebServerFactoryCustomizerConfiguration {
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
public static class JettyWebServerFactoryCustomizerConfiguration {
@Bean
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration
@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
public static class UndertowWebServerFactoryCustomizerConfiguration {
@Bean
public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(
Environment environment, ServerProperties serverProperties) {
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
}
}
}
可以看待spring-boot默认支持tomcat,tc-server,Jetty,Undertow web容器。
3.5.1、http端口
使用:server.port=8080配置,-1禁用http,0随机端口启动应用,便于测试
3.5.2、ssl配置
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
3.5.3、其他配置
在JacksonAutoConfiguration中,声明使用Jackson进行json序列化
在HttpMessageConvertersAutoConfiguration中,声明了默认的HttpMessageConverter;
在JmxAutoConfiguration中,声明了JMX功能。
禁用spring.jmx.enabled=false
四、gradle构建多模块项目
1、可以使用工具或者命令创建
mkdir springboot-mm
cd springboot-mm
gradle init
目录结构:
修改gradleParent的相关配置
settings.gradle
rootProject.name = ''gradle-mvc4''
include ''demo01-thymeleaf''
build.gradle
allprojects {
ext {
springBootVersion = ''2.0.7.RELEASE''
}
apply plugin: ''java''
apply plugin: ''idea''
// JVM 版本号要求
sourceCompatibility = 1.8
targetCompatibility = 1.8
group = ''com.github.bjlhx15.gradle''
version = ''0.0.1-SNAPSHOT''
// java编译的时候缺省状态下会因为中文字符而失败
[compileJava,compileTestJava,javadoc]*.options*.encoding = ''UTF-8''
repositories {
mavenCentral()
}
dependencies {
implementation ''org.springframework.boot:spring-boot-starter-web''
compile group: ''org.springframework.boot'', name: ''spring-boot-starter-thymeleaf'', version: ''2.0.7.RELEASE''
testImplementation ''org.springframework.boot:spring-boot-starter-test''
}
}
子项目build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: ''org.springframework.boot''
apply plugin: ''io.spring.dependency-management''
archivesBaseName = ''demo01-thymeleaf''
代码参看:https://github.com/bjlhx15/gradle-mvc4
ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2...
A.Arcade Game(康拓展开)
题意:
给出一个每个数位都不同的数n,进行一场游戏。每次游戏将n个数的每个数位重组。如果重组后的数比原来的数大则继续游戏,否则算输。如果重组后的数是最大的数则算赢,问赢的概率。
题解:
用康拓展开求出n是第几大的数,然后递推后面的概率。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
char s[15];
double ans;
int fac[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
double cal(char *s) {
int res = 0;
int k = strlen(s);
for(int i = 0; i < k; i++) {
int cnt = 0;
for(int j = i+1; j < k; j++) if(s[j]<s[i]) cnt++;
res += fac[k-i-1]*cnt;
}
if(res==fac[k]-1) return 0;
double ans = 1.0/fac[k];
for(int i = res; i < fac[k]-2; i++) ans += ans/fac[k];
return ans;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%s", s);
printf("%.9lf\n", cal(s));
}
}
B.Unlucky Teacher(模拟)
题意:
Q个题目和M个学生的判卷,求出每道题的答案。如果求不出则输出?。
题解:
模拟即可。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int q, m;
int num[105], state[105];
char ans[105];
char s1[2], s2[2];
int main() {
scanf("%d", &t);
while(t--) {
memset(state, 0, sizeof(state));
memset(num, 0, sizeof(num));
scanf("%d%d", &q, &m);
while(m--) {
for(int i = 1; i <= q; i++) {
scanf("%s%s", s1, s2);
if(s2[0]==''T'') num[i] = -1, ans[i] = s1[0];
else {
if((num[i]==-1)||((state[i]&(1<<s1[0]-''A''))>0)) continue;
state[i] |= 1<<s1[0]-''A'';
num[i]++;
if(num[i]==3) {
for(int j = 0; j < 4; j++)
if(!(state[i]&(1<<j))) {
ans[i] = ''A''+j;
break;
}
num[i] = -1;
}
}
}
}
for(int i = 1; i <= q; i++) {
if(num[i]>-1) printf("?");
else printf("%c", ans[i]);
if(i < q) printf(" ");
}
puts("");
}
}
C.Connecting Graph(并查集+二分)
题意:
初始有n个点,m次操作。每次操作加一条边或者询问两个点第一次连通的时刻(若不连通输出-1)。
题解:
GYM - 100814 C.Connecting Graph


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int t;
int n, m;
int u, v, k;
int f[N], num[N];
vector<pair<int, int> > g[N];
vector<int> c[N];
bool check(int x) {
int l = 0, r = g[u].size()-1;
while(l <= r) {
int mid = l+r>>1;
if(g[u][mid].first <= x) l = mid+1;
else r = mid-1;
}
int p1 = g[u][r].second;
l = 0, r = g[v].size()-1;
while(l <= r) {
int mid = l+r>>1;
if(g[v][mid].first <= x) l = mid+1;
else r = mid-1;
}
int p2 = g[v][r].second;
if(p1==p2) return 1;
return 0;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
num[i] = 1;
f[i] = i;
c[i].clear();
g[i].clear();
c[i].push_back(i);
g[i].push_back(make_pair(0, i));
}
for(int i = 1; i <= m; i++) {
scanf("%d%d%d", &k, &u, &v);
if(k&1) {
u = f[u]; v = f[v];
if(u!=v) {
if(num[u]>num[v]) swap(u, v);
for(int j = 0; j < num[u]; j++) {
c[v].push_back(c[u][j]);
f[c[u][j]] = v;
g[c[u][j]].push_back(make_pair(i, v));
}
num[v] += num[u];
num[u] = 0;
c[u].clear();
}
}
else {
int l = 0, r = i-1;
while(l<=r) {
int mid = l+r>>1;
if(check(mid)) r = mid-1;
else l = mid+1;
}
if(check(r+1)) printf("%d\n", r+1);
else puts("-1");
}
}
}
}
D.Frozen Rivers
题意:
一棵n个节点的树,每条边代表一条河。从点1开始边以每秒1个单位开始融化。每个点连的边(不包括连向父亲的)有一条融化完时剩下的该点连的边融化速度降为0.5。q次询问,每次询问某个时刻融化到叶子节点的数量。
题解:
设minn[u]代表节点u的边中权值最小的那个,将点u所有边的权值加上他们与minn[u]的差值。即每条边的权值翻倍再减去minn[u]。
这样处理完之后就省去了0.5的限制。问题变成了求叶子节点到根节点的距离。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
int t;
int n, q, p, c;
int tot;
int head[N], to[N], nxt[N], w[N], minn[N];
int cnt;
ll tim, num[N];
void dfs(int u, ll val) {
if(minn[u]==inf) {
num[++cnt] = val;
return ;
}
for(int i = head[u]; ~i; i = nxt[i]) {
w[i] = 2*w[i]-minn[u];
dfs(to[i], val+w[i]);
}
}
int main() {
scanf("%d", &t);
while(t--) {
tot = cnt = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) head[i] = -1, minn[i] = inf;
for(int i = 2; i <= n; i++) {
scanf("%d%d", &p, &c);
to[++tot] = i; nxt[tot] = head[p]; head[p] = tot, w[tot] = c;
minn[p] = min(minn[p], c);
}
dfs(1, 0);
sort(num+1, num+cnt+1);
scanf("%d", &q);
while(q--) {
scanf("%lld", &tim);
int ans = upper_bound(num+1, num+cnt+1, tim)-num-1;
printf("%d\n", ans);
}
}
}
E.Palmyra(dp)
题意:
给出n*m的矩阵。从点(1,1)出发,可以向右或者向下移动,最后走到(n,m)。将路途上的点值乘起来,问最后的值拿6进制表示末尾最多有几个0。
题解:
题意可以理解为,使最后2的因子数和3的因子数中的最小值最大。
dp[i][j][k]表示走到(i,j),3的因子数为k时2的因子数最多是多少。


#include <bits/stdc++.h>
using namespace std;
int t;
int n, m;
int q[105][105][3];
int dp[105][105][1505];
int main() {
scanf("%d", &t);
while(t--) {
memset(q, 0, sizeof(q));
memset(dp, -1, sizeof(dp));
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
scanf("%d", &q[i][j][0]);
int t = q[i][j][0];
while(t%2 == 0) {
q[i][j][1]++;
t /= 2;
}
while(t%3 == 0) {
q[i][j][2]++;
t /= 3;
}
}
}
dp[1][1][q[1][1][2]] = q[1][1][1];
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
int n2 = q[i][j][1];
int n3 = q[i][j][2];
for(int k = 0; k + n3 <= 1500; k++) {
if(dp[i][j-1][k] != -1)
dp[i][j][k+n3] = max(dp[i][j][k+n3], dp[i][j-1][k]+n2);
if(dp[i-1][j][k] != -1)
dp[i][j][k+n3] = max(dp[i][j][k+n3], dp[i-1][j][k]+n2);
}
}
}
int ans = 0;
for(int i = 1; i <= 1500; i++) {
int nn = min(dp[n][m][i], i);
ans = max(ans, nn);
}
printf("%d\n", ans);
}
return 0;
}
F.Geometry
题意:
给出长和宽,判断时正方形还是矩形。
题解:
判断w是否等于h。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int w, h;
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &w, &h);
if(w==h) puts("Square");
else puts("Rectangle");
}
}
G.It is all about wisdom(最短路+二分)
题意:
给出一个图,图中的每条边有使用的最低限制值和花费。问从1走到n在总花费小于k的前提下的最小限制值是多少。
题解:
标准的二分套最短路的题型。二分最小的限制值即可。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
int t;
int n, m, k;
int u, v, c, l, r;
int vis[N], dis[N];
struct node {
int to, v, lim;
node(int a, int b, int c) {
to = a; v = b; lim = c;
}
};
vector<node> g[N];
bool check(int x) {
queue<int> q;
for(int i = 1; i <= n; i++) vis[i] = 0, dis[i] = inf;
q.push(1);
vis[1] = 1;
dis[1] = 0;
while(!q.empty()) {
int v = q.front();
q.pop();
vis[v] = 0;
int len = g[v].size();
for(int i = 0; i < len; i++) {
if(g[v][i].lim > x) continue;
if(g[v][i].v+dis[v] < dis[g[v][i].to]) {
dis[g[v][i].to] = g[v][i].v+dis[v];
if(!vis[g[v][i].to]) {
q.push(g[v][i].to);
vis[g[v][i].to] = 1;
}
}
}
}
if(dis[n] < k) return 1;
return 0;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &k);
r = 0;
for(int i = 1; i <= n; i++) g[i].clear();
while(m--) {
scanf("%d%d%d%d", &u, &v, &c, &l);
g[u].push_back(node(v, c, l));
g[v].push_back(node(u, c, l));
r = max(r, l);
}
l = 1;
while(l<=r) {
int mid = l+r>>1;
if(check(mid)) r = mid-1;
else l = mid+1;
}
if(check(r+1)) printf("%d\n", r+1);
else puts("-1");
}
}
I.Salem
题意:
给出n个数,求数对中最大的hamming距离。
题解:
每两个数求一下异或之后二进制下1个数量即可,输出最大值。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t, n;
int a[105];
int main() {
scanf("%d", &t);
while(t--) {
int ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
for(int j = 1; j < i; j++) {
int p = a[i]^a[j], cnt = 0;
for(int k = 20; k >= 0; k--) {
if(p&(1<<k)) cnt++;
}
ans = max(ans, cnt);
}
}
printf("%d\n", ans);
}
}
J.Game
题意:
给出合并规则表。两个人轮流进行操作,每次选择从最左面或者最右面开始每两个合并成一个。如果最后剩的是元音字符,就是Salah获胜。否则Marzo获胜。
题解:
暴力维护每一种情况。用1表示S获胜,0表示M获胜。
当S操作时,若两种情况存在1,则当前为1。
当M操作时,若两种情况存在0,则当前为0。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4+10;
int t;
int tot;
int len[N];
char s[N][N];
char g[30][30];
char cmp[5] = {''a'', ''e'', ''i'', ''o'', ''u''};
bool dfs(int num, int k) {
if(len[num] < 3) {
char c;
if(len[num]==1) c = s[num][0];
else c = g[s[num][0]-''a''][s[num][1]-''a''];
for(int i = 0; i < 5; i++) if(c==cmp[i]) return true;
return false;
}
++tot;
for(int i = 0; i < len[num]; i+=2) {
if(i==len[num]-1) s[tot][i/2] = s[num][i];
else s[tot][i/2] = g[s[num][i]-''a''][s[num][i+1]-''a''];
}
len[tot] = (len[num]+1)/2;
bool res = dfs(tot, k^1);
if(len[num]&1) {
++tot;
s[tot][0] = s[num][0];
for(int i = 1; i < len[num]; i+=2) {
s[tot][i/2+1] = g[s[num][i]-''a''][s[num][i+1]-''a''];
}
len[tot] = (len[num]+1)/2;
if(k) res &= dfs(tot, k^1);
else res |= dfs(tot, k^1);
}
return res;
}
int main() {
scanf("%d", &t);
while(t--) {
tot = 0;
for(int i = 0; i < 26; i++) scanf("%s", g[i]);
scanf("%s", s[0]);
len[0] = strlen(s[0]);
if(dfs(0, 0)) puts("Salah");
else puts("Marzo");
}
}
K.PhD math
题意:
给出a,b,n,p(a<b)。求a/b的前n位数中有多少字串整除p。
题解:
从1扫到n。维护每一位新增的余数。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int t;
ll a, b;
int n, p;
int bit[N];
int v1[205], v2[205];
ll ans;
int main() {
scanf("%d", &t);
while(t--) {
ans = 0;
memset(v1, 0, sizeof(v1));
memset(v2, 0, sizeof(v2));
scanf("%lld%lld%d%d", &a, &b, &n, &p);
for(int i = 1; i <= n; i++) {
a *= 10;
bit[i] = a/b;
a = a%b;
}
for(int i = 1; i <= n; i++) {
for(int j = 0; j < p; j++) {
if(i&1) v1[j] = 0;
else v2[j] = 0;
}
for(int j = 0; j < p; j++) {
if(i&1) v1[(j*10+bit[i])%p] += v2[j];
else v2[(j*10+bit[i])%p] += v1[j];
}
if(i&1) v1[bit[i]%p]++, ans += v1[0];
else v2[bit[i]%p]++, ans += v2[0];
}
printf("%lld\n", ans);
}
}
L.Candy Jars(博弈)
题意:
N个罐子,每个罐子有一定数量的糖。两个人轮流操作,每次选定一罐,把其他罐中的糖都扔掉。然后把选定罐中的糖任意分配给每个罐,但要保证每个罐中都有糖。不能操作者判输。
题解:
只要有一个罐子糖数必胜则操作者必胜。
当所有罐子糖数小于N时无法给所有罐子分配糖,必输。
当存在罐子糖数在[N,N(N-1)]时,可以把糖分成必输态,即分成所有罐子糖数小于N的状态,这时必胜。
然后举例发现N(N-1)是一个循环节,取模就可以了。


#include <bits/stdc++.h>
using namespace std;
int t, n;
int k;
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
int ans = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &k);
k %= n*(n-1);
if(k==0 || k > n-1) ans = 1;
}
if(ans) puts("Alice");
else puts("Bob");
}
}
M.Building Force Fields(dp)
题意:
按x升序给出n个点的二维坐标,并保证没有两个点x坐标相同。可以在任意两个点之间连边,最后要保证每个点都在连边之下(或在连边上)。问最小的连边总长。
题解:
dp[i]表示第i个点结尾的最小总连边长。
转移是枚举i向第j(1<=j<i)个点连边,要保证连边上方无点。即第i和第j个点的斜率比第i个点和(j,i)范围内的点的斜率都小。最后取最小值。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t, n;
double dp[1005];
struct node {
ll x, y;
}a[1005];
double dis(int n1, int n2) {
return sqrt((a[n1].x-a[n2].x)*(a[n1].x-a[n2].x)+(a[n1].y-a[n2].y)*(a[n1].y-a[n2].y));
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld%lld", &a[i].x, &a[i].y);
dp[1] = dis(1, 2);
for(int i = 2; i <= n; i++) {
int pos = i-1;
dp[i] = min(dp[i-2], dp[i-1])+dis(i, i-1);
for(int j = i-2; j >= 1; j--) {
if((a[i].y-a[pos].y)*(a[i].x-a[j].x) >= (a[i].y-a[j].y)*(a[i].x-a[pos].x)) {
dp[i] = min(dp[i], min(dp[j-1], dp[j])+dis(i, j));
pos = j;
}
}
}
printf("%.6lf\n", dp[n]);
}
}
com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy的实例源码
public static String convertToSnakeCaseIfSupported(String name,Class<?> specType) { RosettaNaming rosettaNaming = getAnnotation(specType,RosettaNaming.class); boolean snakeCasing = rosettaNaming != null && (rosettaNaming.value().equals(LowerCaseWithUnderscoresstrategy.class) || rosettaNaming.value().equals(SnakeCaseStrategy.class)); if (snakeCasing && !name.contains("_")) { return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERscore,name); } return name; }
@Test public void customPropertyNamingStrategyField() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERscoreS"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy(),is(instanceOf(LowerCaseWithUnderscoresstrategy.class))); }
@Test public void customPropertyNamingStrategyClass() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresstrategy"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy(),is(instanceOf(LowerCaseWithUnderscoresstrategy.class))); }
/** * Creates client applying default configuration and then customizations. Example: * <pre> * {@code * new FeignClient(apiUrl,builder -> builder.requestInterceptor(template -> * template.header("Authorization","bearer " + token))); * } * </pre> * @param url endpoint url * @param customizations custom configuration that should be applied after defaults */ public FeignClient(String url,Function<Builder,Builder> customizations) { Objects.requireNonNull(url); Objects.requireNonNull(customizations); final ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES); mapper.setPropertyNamingStrategy(new LowerCaseWithUnderscoresstrategy()); // avoid duplication of slashes final String targetUrl = StringUtils.removeEnd(url,"/"); // first applies defaults and then custom configuration final Builder builder = customizations.apply(Feign.builder() .encoder(new JacksonEncoder()) .decoder(new JacksonDecoder(mapper)) .options(new Request.Options(CONNECT_TIMEOUT,READ_TIMEOUT)) .logger(new ScramblingSlf4jLogger(FeignClient.class)) .logLevel(feign.Logger.Level.BASIC) .errorDecoder(new CompositeErrorDecoder(new FeignErrorDecoderHandler("description")))); this.applicationResource = builder.target(CcApplicationResource.class,targetUrl); this.organizationResource = builder.target(CcOrganizationResource.class,targetUrl); this.serviceResource = builder.target(CcServiceResource.class,targetUrl); this.serviceBindingResource = builder.target(CcServiceBindingResource.class,targetUrl); this.spaceResource = builder.target(CcSpaceResource.class,targetUrl); this.userResource = builder.target(CcUserResource.class,targetUrl); this.buildpackResource = builder.target(CcBuildpacksResource.class,targetUrl); this.quotaResource = builder.target(CcQuotaResource.class,targetUrl); }
@Bean public ObjectMapper objectMapper() { return new ObjectMapper() .setPropertyNamingStrategy(new LowerCaseWithUnderscoresstrategy()) .disable(DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES); }
com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy的实例源码
@Test public void customPropertyNamingStrategyField() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:SNAKE_CASE"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy()) .isinstanceOf(SnakeCaseStrategy.class); }
@Test public void customPropertyNamingStrategyClass() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy()) .isinstanceOf(SnakeCaseStrategy.class); }
public static String convertToSnakeCaseIfSupported(String name,Class<?> specType) { RosettaNaming rosettaNaming = getAnnotation(specType,RosettaNaming.class); boolean snakeCasing = rosettaNaming != null && (rosettaNaming.value().equals(LowerCaseWithUnderscoresstrategy.class) || rosettaNaming.value().equals(SnakeCaseStrategy.class)); if (snakeCasing && !name.contains("_")) { return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERscore,name); } return name; }
@Test public void customPropertyNamingStrategyField() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:SNAKE_CASE"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy()) .isinstanceOf(SnakeCaseStrategy.class); }
@Test public void customPropertyNamingStrategyClass() throws Exception { this.context.register(JacksonAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context,"spring.jackson.property-naming-strategy:com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy"); this.context.refresh(); ObjectMapper mapper = this.context.getBean(ObjectMapper.class); assertthat(mapper.getPropertyNamingStrategy()) .isinstanceOf(SnakeCaseStrategy.class); }
关于无法使用Spring Boot + GORM + Gradle设置NamingStrategy和无法使用com.mysql.jdbc.driver的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于001-快速搭建Spring web应用【springboot 2.0.4】-gradle、springboot的启动过程分析、gradle多模块构建、ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2...、com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy的实例源码、com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy的实例源码的相关知识,请在本站寻找。
本文标签: