sprint boot spring-web

 

1. 如何找到tomcat

ServletWebServerFactoryConfiguration下面有三个EmbeddedTomcat,EmbeddedJetty,EmbeddedUndertow注解为@Configuratio的类,但是它们有condition, 只有满足条件才会被注册,因为spring-boot-starter-web项目中的pom.xml默认使用tomcat

org.springframework.boot

spring-boot-starter-tomcat

所以只有tomcatServletWebServerFactory的注解@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })满足条件而被注册,ServletWebServerApplicationContext.getWebServerFactory会得到TomcatServletWebServerFactory

 

2. 如何不使用server.xml

TomcatServletWebServerFactory.getWebServer会获得WebServer,它不需server.xml,而是在getWebServer方法中通过硬编码提供的默认配置构造了Connector,Host,Engine等实例。

 

3. 如何不使用web.xml配置servlet,filter,listener

TomcatServletWebServerFactory.getWebServer方法中会new一个Tomcat,它是apache提供的,可以在没有web.xml的时候来启动tomcat容器。TomcatWebServer.initialize()会调用{this.tomcat.start()}来启动tomcat容器的线程。

DispatcherServletAutoConfiguration$DispatcherServletConfiguration.dispatcherServlet()会自动注册spring web的前端控制器dispatcherServlet到容器中。

tomcat的映射原理是ApplicationContextFacade根据url来找到对应的servlet,所以spring要通过ServletRegistrationBean.addRegistration方法将dispatcherServlet注册进tomcat的ApplicationContextFacade容器。

ServletRegistrationBean里有dispatcher的默认映射配置为/*, 它会把该映射设置到apache的ApplicationServletRegistration.addMapping中。至此tomcat可以处理/*的请求。

 

4. 如何使用view(jsp,thymeleaf)

如果你引入thymeleaf jar,则ThymeleafAutoConfiguration的条件配置满足,会自动配置以下主要的thymeleaf功能类:

ThymeleafProperties:通过application.properties里的前辍为"spring.thymeleaf"来设置ThymeleafProperties类。

ThymeleafViewResolver:将逻辑视图名称解析为Thymeleaf模板视图。

SpringTemplateEngine:处理模板并渲染结果。

TemplateResolver:加载Thymeleaf模板。

 

5. 流程:

所有请求都会被dispatcherServlet捕获,spring将apache的request,response封装成ServletWebRequest,

再ServletInvocableHandlerMethod.invokeAndHandle(ServletWebRequest),该方法有两个功能invoke和handle:

1). invoke是将请求分派到具体的spring mvc的controller的方法上去执行。

2). handle是将invoke生成的model和view渲染成html输出。具体过程如下:

不同的view有不同的HandlerMethodReturnValueHandler,RequestMappingHandlerAdapter.getDefaultReturnValueHandlers()里有15个默认ReturnValueHandler。遍历DefaultReturnValueHandlers找到第一满足HandlerMethodReturnValueHandler.supportsReturnType==view的handler来处理,如果action返回字符串,则交由ViewNameMethodReturnValueHandler来处理,handler仅作ModelAndViewContainer.setViewName(viewName);处理。

接下来RequestMappingHandlerAdapter.getModelAndView(ModelAndViewContainer)更新model并获取ModelAndView{viewName和model}对象。

接下来DispatcherServlet.render(ModelAndView, request, response);使用model和template来渲染view。ContentNegotiatingViewResolver它是一个总控,它会resolveViewName(viewName)找到对应的View,至此template还没有加载。

接下来View.render(model, request, response); 会调用SpringTemplateEngine.process(templateName, context, response.getWriter()); 在此方法中主要是TemplateResolution.templateResource加载template,并对里面的tag进行动态解析,最后使用response.getWriter()输出。

 

 

6. 扩展自定义servlet

 

@Configuration

public class WebMvcConfig {

@Bean

public ServletRegistrationBean helloServletBean() {

return new ServletRegistrationBean(new HelloServlet(), "/hello");

}

 

}

 

class HelloServlet extends HttpServlet {

 

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

 

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.getWriter().append("hello servlet").flush();

}

 

}

你可能感兴趣的:(sprint boot spring-web)