1SpringMVC自動構成の概要
Spring Bootは、ほとんどのアプリケーションで適切に機能するSpring MVCの自動構成を提供します(ほとんどのシナリオでカスタム構成は必要ありません)
自動構成により、Springのデフォルトに加えて次の機能が追加されます。
-
ContentNegotiatingViewResolver
とBeanNameViewResolver
豆の包含。 -
- コンテンツネゴシエーションビューリゾルバーとBeanNameビューリゾルバー
-
WebJarsのサポートを含む静的リソースの提供のサポート(このドキュメントの後半で説明します))。
-
- 静的リソース(webjarを含む)
-
Converter
、、GenericConverter
およびFormatter
Beanの自動登録。 -
- 自動登録
Converter,GenericConverter,Formatter
- 自動登録
-
のサポート
HttpMessageConverters
(このドキュメントの後半で説明します)。 -
- サポート
HttpMessageConverters
(後で、原則を理解するためにコンテンツネゴシエーションに協力します)
- サポート
-
の自動登録
MessageCodesResolver
(このドキュメントの後半で説明します)。 -
- 自動登録
MessageCodesResolver
(国際化用)
- 自動登録
-
静的
index.html
サポート。 -
- 静的index.htmlページのサポート
-
カスタム
Favicon
サポート(このドキュメントの後半で説明します)。 -
- カスタマイズ
Favicon
- カスタマイズ
-
ConfigurableWebBindingInitializer
Beanの自動使用(このドキュメントの後半で説明します)。 -
- 自動使用
ConfigurableWebBindingInitializer
、(DataBinderは要求データをJavaBeansにバインドする責任があります)
- 自動使用
これらのSpringBootMVCのカスタマイズを維持し、MVCのカスタマイズ(インターセプター、フォーマッター、ビューコントローラー、およびその他の機能)をさらに作成したい場合は、独自@Configuration
のタイプのクラスを追加できますが、。は追加できWebMvcConfigurer
ません @EnableWebMvc
。
@EnableWebMvcアノテーションは使用しないでください。 @Configuration
+ カスタムルールを使用WebMvcConfigurer
RequestMappingHandlerMapping
、、、RequestMappingHandlerAdapter
またはのカスタムインスタンスを提供しExceptionHandlerExceptionResolver
、それでもSpring Boot MVCのカスタマイズを維持したい場合は、タイプのBeanを宣言し、WebMvcRegistrations
それを使用してそれらのコンポーネントのカスタムインスタンスを提供できます。
デフォルトの基礎となるコンポーネントを変更することを宣言しますWebMvcRegistrations
Spring MVCを完全に制御したい場合は、で注釈を付けた独自の@Configuration
注釈を@EnableWebMvc
追加するか、の@Configuration
JavadocDelegatingWebMvcConfiguration
で説明されているように独自の注釈を付けて追加することができます@EnableWebMvc
。
使用する @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC
2簡単な機能分析
2.1静的リソースアクセス
2.1.1静的リソースディレクトリ
静的リソースがクラスパス上にある限り:呼び出された/static
(または/public
または/resources
または/META-INF/resources
-
アクセス:現在のプロジェクトルートパス/+静的リソース名
-
原則:
静态映射/**
。リクエストが届いたら、まずコントローラーに移動して、リクエストを処理できるかどうかを確認します。処理できないすべてのリクエストは、静的リソースハンドラーに渡されます。静的リソースが見つからない場合は、404ページで応答します。
-
デフォルトの静的リソースパスを変更します
spring: web: resources: static-locations: classpath:/abc
2.1.2静的リソースアクセスプレフィックス
(デフォルトではプレフィックスなし)
spring:
mvc:
static-path-pattern: /res/**
現在のプロジェクト++static-path-pattern
静的リソース名=静的リソースフォルダーで検索
2.1.3 webjar
自動マップ/ webjars / **
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
アクセスアドレス:http:// localhost:8080 / webjars / jquery / 3.6.0 / dist / jquery.js背後のアドレスは、依存関係のパッケージパスに従う必要があります
2.2ウェルカムページのサポート
-
静的リソースパスの下のindex.html
-
静的リソースパスを構成できます
-
ただし、静的リソースのアクセスプレフィックスは設定できません。そうしないと、デフォルトでindex.htmlにアクセスできません。
spring: # mvc: # static-path-pattern: /res/** 这个会导致welcome page功能失效 web: resources: static-locations: classpath:/abc
-
-
コントローラは/indexを処理できます
2.3カスタマイズFavicon
favicon.icoは、静的リソースディレクトリに配置できます。(アイコンが表示されない場合は、ブラウザのキャッシュをクリアするか、ブラウザを閉じて再度開きます)
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致 Favicon 功能失效
2.4静的リソース構成の原則
-
SpringBootは、デフォルトのロード
xxxAutoConfiguration
クラス(自動構成クラス)を開始します -
SpringMVC関数の自動構成クラス
WebMvcAutoConfiguration
が有効になります@Configuration( proxyBeanMethods = false ) @ConditionalOnWebApplication( type = Type.SERVLET ) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({ WebMvcConfigurationSupport.class}) @AutoConfigureOrder(-2147483638) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}) public class WebMvcAutoConfiguration { }
-
コンテナの中身。
@Configuration( proxyBeanMethods = false ) @Import({ WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware { }
-
構成ファイルの関連するプロパティはxxxにバインドされています。WebMvcProperties == spring.mvc、WebProperties == spring.web
2.4.1構成クラスにはパラメーター化されたコンストラクターが1つだけあります
//有参构造器所有参数的值都会从容器中确定
//WebProperties webProperties;获取和spring.web绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath
//ServletRegistrationBean 给应用注册Servlet、Filter....
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.resourceProperties = webProperties.getResources();
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
this.mvcProperties.checkConfiguration();
}
2.4.2リソース処理のデフォルトルール
これは、静的リソースにアクセスするためのデフォルトの構成ルールです。jQueryの静的リソースが導入された後、このプレフィックスがデフォルトで構成され、静的リソースアクセスパス/webjars/**
も追加されます。/META-INF/resources/webjars/
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{
resource});
}
});
}
}
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
this.addResourceHandler(registry, pattern, (registration) -> {
registration.addResourceLocations(locations);
});
}
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, Consumer<ResourceHandlerRegistration> customizer) {
if (!registry.hasMappingForPattern(pattern)) {
ResourceHandlerRegistration registration = registry.addResourceHandler(new String[]{
pattern});
customizer.accept(registration);
registration.setCachePeriod(this.getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
this.customizeResourceHandlerRegistration(registration);
}
}
spring:
# mvc:
# static-path-pattern: /res/**
resources:
static-locations: classpath:/abc
add-mappings: false #禁用所有静态资源规则
@ConfigurationProperties("spring.web")
public class WebProperties {
private Locale locale;
private WebProperties.LocaleResolver localeResolver;
private final WebProperties.Resources resources;
public WebProperties() {
this.localeResolver = WebProperties.LocaleResolver.ACCEPT_HEADER;
this.resources = new WebProperties.Resources();
}
public Locale getLocale() {
return this.locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public WebProperties.LocaleResolver getLocaleResolver() {
return this.localeResolver;
}
public void setLocaleResolver(WebProperties.LocaleResolver localeResolver) {
this.localeResolver = localeResolver;
}
public WebProperties.Resources getResources() {
return this.resources;
}
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{
"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private boolean customized;
private final WebProperties.Resources.Chain chain;
private final WebProperties.Resources.Cache cache;
public Resources() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.customized = false;
this.chain = new WebProperties.Resources.Chain();
this.cache = new WebProperties.Resources.Cache();
}
2.4.3ウェルカムページの処理ルール
// HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
return welcomePageHandlerMapping;
}
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
if (welcomePage != null && "/**".equals(staticPathPattern)) {
//要用欢迎页功能,必须是/**
logger.info("Adding welcome page: " + welcomePage);
this.setRootViewName("forward:index.html");
} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
//调用Controller /index
logger.info("Adding welcome page template: index");
this.setRootViewName("index");
}
}
2.4.4ファビコン
ブラウザはアイコンを取得するために/faviconリクエストを送信しますが、セッション全体では取得されません。