[TOC]html
基礎Servlet架構 前端
核心架構:前端控制器java
怎麼講呢?就是很傳統的使用Spring Framework WEB MVC的方式,例如Bean配置在xml中,前端控制器配置在web.xml中等。git
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.3.RELEASE</version> </dependency> </dependencies>
<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
<context:component-scan base-package="com.jimisun.web"/> <mvc:annotation-driven/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
@Controller public class HelloSpringController { @RequestMapping("") public String index(){ return "index"; } }
所謂的新時代相比確定是在傳統時代上的升級。提到升級咱們首先會想到會提高使用的便捷程度以及性能。github
@Configuration @EnableWebMvc public class WebDispatcherServletConfigure implements WebMvcConfigurer { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver(); resourceViewResolver.setViewClass(JstlView.class); resourceViewResolver.setPrefix("/WEB-INF/jsp/"); resourceViewResolver.setSuffix(".jsp"); return resourceViewResolver; } }
在Spring.xml文件中則不用再配置處理器映射器,處理器適配器和內部資源視圖解析器(JSP)。只須要保留<context:component-scan base-package="com.jimisun.web"/>
以便發現咱們自定義的前端控制器配置類WebDispatcherServletConfigure
。由於@EnableWebMvc
註解爲咱們自動配置內部資源視圖解析器不符合咱們自定義的要求,因此上述代碼中咱們使用@Bean
註解從新裝配了InternalResourceViewResolver
類。web
基於註解驅動配置的重點是@EnableWebMvc
註解,此模塊註解將導入DelegatingWebMvcConfiguration
配置類,該類又集成了WebMvcConfigurationSupport
類。WebMvcConfigurationSupport
中則配置了一些關於 WEB MVC的相關Bean;例如:RequestMappingHandlerMapping
,ContentNegotiationManager
,HandlerMapping
,BeanNameUrlHandlerMapping
,RequestMappingHandlerAdapter
,ViewResolver
等等......spring
原理 : 在web容器啓動時爲提供給第三方組件機會作一些初始化的工做,例如註冊servlet或者filtes等,servlet規範中經過ServletContainerInitializer實現此功能。每一個框架要使用ServletContainerInitializer就必須在對應的jar包的META-INF/services 目錄建立一個名爲javax.servlet.ServletContainerInitializer的文件,文件內容指定具體的ServletContainerInitializer實現類,那麼,當web容器啓動時就會運行這個初始化器作一些組件內的初始化工做。通常伴隨着ServletContainerInitializer一塊兒使用的還有HandlesTypes註解,經過HandlesTypes能夠將感興趣的一些類注入到ServletContainerInitializerde的onStartup方法做爲參數傳入。springboot
咱們從spring-web的依賴包中找到這個文件,因此咱們能夠將前端控制器在Servlet容器啓動的時候將Spring WEB MVC的前端控制器添加入Servlet容器中,而不用再配置在web.xml文件中。架構
咱們能夠看一下Spring的這個SpringServletContainerInitializer
類mvc
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { ...... }
咱們能夠看到Spring定義的這個類實現了Servlet3.0的ServletContainerInitializer
接口,而且標註了@HandlesTypes
;表示將實現WebApplicationInitializer.class
接口的類注入到ServletContainerInitializer
的回調方法onStartup()
進行初始化。
咱們從上面圖能夠看到WebApplicationInitializer接口的實現類共有四個,因此就意味着咱們自定義一個類實現這三個抽象方法其中的一個就行。下面是咱們自定義的Servlet容器初始化器類。
public class DefaultAnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[0]; } protected Class<?>[] getServletConfigClasses() { return new Class[]{DispathcherConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } }
getServletMappings()
方法用來返回前端控制器要攔截的路徑形式。其中getRootConfigClasses()
方法用於配置Spring Framework與Service,response有關的Bean;而getServletConfigClasses()
方法則用來配置Spring Framework中的WEB層相關的Bean。資料參考 :https://stackoverflow.com/questions/35258758/getservletconfigclasses-vs-getrootconfigclasses-when-extending-abstractannot
總的來講只要自定義一個類,實現WebApplicationInitializer接口便可;咱們就能夠不用在web.xml中配置前端控制器了。
Spring Boot從一下三個方面來簡化WEB開發;分別是「自動裝配」,「條件裝配」,「外部化配置」 三個方面來簡化WEB MVC開發。
SpringBooot對於WEB MVC的徹底自動裝配主要體如今一下三個方面。
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
從徹底自動裝配能夠看到,SpringBoot替咱們裝配了不少東西;可是在大部分狀況下就是基於條件進行裝配的,既知足某某條件纔會進行裝配。仍是來看一下前端控制器自定裝配類org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(DispatcherServlet.class) @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class) public class DispatcherServletAutoConfiguration { }
從該類的註解上咱們能夠知道@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
該類的裝配順序,@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
在WEB容器裝配以後再進行裝配,@Configuration
可被管理的Bean,@ConditionalOnWebApplication(type = Type.SERVLET)
知足條件爲WEB類型應用,@ConditionalOnClass(DispatcherServlet.class)
知足條件存在DispatcherServlet
類。
能夠看到咱們須要知足兩個條件SpringBoot纔會爲咱們裝配這個前端控制器DispatcherServlet
類。
關於WEB MVC的外部化配置咱們須要瞭解一下WebMvcProperties
類和ResourceProperties類;分別對WebMvc和資源文件進行配置。
@ConfigurationProperties(prefix = "spring.mvc") public class WebMvcProperties { ....... }
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false) public class ResourceProperties { ...... }
從註解上咱們能夠了解到,咱們能夠在application.properties
文件或者application.yml
文件中進行相關配置。
例如:SpringBoot在自動裝配WEB MVC組件的時候裝配了一個內部資源視圖解析器(JSP)
@Bean @ConditionalOnMissingBean public InternalResourceViewResolver defaultViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix(this.mvcProperties.getView().getPrefix()); resolver.setSuffix(this.mvcProperties.getView().getSuffix()); return resolver; }
其中this.mvcProperties.getView().getPrefix()
就是從application.properties
文件或者application.yml
文件中獲取的值進行的操做而非硬編碼。
該教程所屬Java工程師之SpringBoot系列教程,本系列相關博文目錄 Java工程師之SpringBoot系列教程前言&目錄