Springboot之---强大的Servlet(六)

简介: 如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找

传统的Servlet容器 Apache Tomcat

这里只记录了部分重要场景
包含核心组件
静态资源处理
类加载
连接器
JDBC数据源

HttpServletResponse

javax.servlet.http.HttpServletResponse

public static void main(String[] args) {
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    while (true) {

        System.out.println(contextClassLoader.getClass().getName());
        ClassLoader parent = contextClassLoader.getParent();
        if (parent == null) {
            break;
        }

    }

    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    System.out.println(systemClassLoader.getClass().getName());
}

除了其中的状态码之外,结合最近的测试其中的实现可具体参考
addHeader方法,getHeader方法等等
BootStrap--system---common---webapp

静态资源处理类org.apache.catalina.servlets.DefaultServlet

注意下包名

大多数情况下我们关注的更多是server.xml中Tomcat的配置,而在web.xml中除了路径映射等配置外

 <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

关于是否是开发模式

 <!--   development         Is Jasper used in development mode? If true,   -->
  <!--                       the frequency at which JSPs are checked for    -->
  <!--                       modification may be specified via the          -->
  <!--                       modificationTestInterval parameter. [true]     -->

由于DefaultServlet是HttpServlet的子类,所以在此不展开讨论
而在server.xml中标签与后台接口是一一绑定的

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

而在JDBC中的大多数类中也遵循此规则,那么就上面这段分析标签Connector则对应
org.apache.catalina.connector.Connector,验证一下标签中对应protocol,connectionTimeout,redirectPort
其中标签对应部分

 /**
     * Defaults to using HTTP/1.1 NIO implementation.
     */
    public Connector() {
        this("org.apache.coyote.http11.Http11NioProtocol");
    }

而在tomcat8.0+中getProtocol对应protocol
redirectPort对应属性默认值

/**
     * The redirect port for non-SSL to SSL redirects.
     */
    protected int redirectPort = 443;

关于标签中connector中这个Http11NioProtocol则在tomcat官方文档中可见其中一句话

When using HTTP connectors (based on APR or NIO/NIO2), Tomcat supports using sendfile to send large static files. These writes, as soon as the system load increases, will be performed asynchronously in the most efficient way. Instead of sending a large response using blocking writes, it is possible to write content to a static file, and write it using a sendfile code. A caching valve could take advantage of this to cache the response data in a file rather than store it in memory. Sendfile support is available if the request attribute org.apache.tomcat.sendfile.support is set to Boolean.TRUE

也可在server.xml中搜索

<!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->

server.port在文件中的位置
<!-- {

  "name": "server.port",
  "type": "java.lang.Integer",
  "description": "Server HTTP port.",
  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
  "defaultValue": 8080
}, -->

重点来了 ServerProperties包含了tomcat,Jetty,Undertow,而在Springboot2.2.6中则存在Netty

那么理所当然,在tomcat中的一些配置也存在于此

/**
 * Maximum amount of worker threads.
 */
private int maxThreads = 200;

/**
 * Minimum amount of worker threads.
 */
private int minSpareThreads = 10;

那么为什么Tomcat被称之为嵌入式容器呢?

在启动时无需自启动容器,在Bootstrap中调用tomcat,另外tomcat中TomcatEmbeddedContext,Embedded即直译为嵌入式
流程
这里记忆有些混乱了,有点找不过来哪里是入口了,但先从TomcatServletWebServerFactoryCustomizer的customize()方法调用找,

private Stream<Wrapper> getLoadOnStartupWrappers(Container[] children) {
        Map<Integer, List<Wrapper>> grouped = new TreeMap<>();
        for (Container child : children) {
            Wrapper wrapper = (Wrapper) child;
            int order = wrapper.getLoadOnStartup();
            if (order >= 0) {
                grouped.computeIfAbsent(order, ArrayList::new);
                grouped.get(order).add(wrapper);
            }
        }
        return grouped.values().stream().flatMap(List::stream);
    }

因为要看下Netty,所以还是重新看下server.properties
我将Spring Boot AutoConfigure升级到了2.6.2,内置的Tomcat就升级到9.0了
为了方便查看才升级的,之前的2.1.x就不截图了
server.properties的位置在configuration的下面的json文件
spring-configuration-metadata.json

{
      "name": "server",
      "type": "org.springframework.boot.autoconfigure.web.ServerProperties",
      "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
}

那既然为了看Netty在这个json文件中同样存在

{
      "name": "server.netty",
      "type": "org.springframework.boot.autoconfigure.web.ServerProperties$Netty",
      "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
      "sourceMethod": "getNetty()"
}

既然在json中存在getNetty等方法,猜测那么对应的ServerProperties也存在对应的方法,
因为存在实例么,tomcat搭配server.xml和web.xml简单看了一下,当然Tomcat还是主要和Servlet的关联关系更为重要,
本身tomcat知识点也最够庞大的,包含类加载器,双拼委派,打破双亲委派、jvm调优等等,可以顺带看下这里的专题

当一次请求发起都发生了什么?

用户通过浏览器进行了一个操作,这个操作可以是输入url地址并回车,或者是点击超链接,或者是在搜索框中输入关键字进行搜索,接着浏览器就捕获到了这个事件
由于 HTTP 协议底层具体的数据传输使用的是 TCP/IP 协议,因此浏览器需要向服务端发出 TCP 连接请求
服务器接受浏览器的连接请求,并经过 TCP 三次握手建立连接
浏览器将请求数据打包成一个 HTTP 协议格式的数据包
浏览器将打包好的数据包推入网络,经过网络传输最终到达服务器指定程序
服务端程序拿到数据包后,根据 HTTP 协议格式进行解包,获取到客户端的意图
得知客户端意图后进行处理,比如提供静态文件或者调用服务端程序获得动态结果
服务器将响应结果按照 HTTP 协议格式打包
服务器将响应数据包推入网络,数据包经过网络传输最终达到到浏览器
浏览器拿到数据包后,按照 HTTP 协议的格式解包,然后对数据进行解析
浏览器将解析后的静态数据(如html、图片)展示给用户

Tomcat 作为一个 HTTP 服务器,主要需要完成的功能是接受连接、解析请求数据、处理请求和发送响应这几个步骤。
作者:若兮缘
链接:https://www.jianshu.com/p/7c9401b85704
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
关于tomcat的架构就取自这篇文章,图文都很喜欢~

导入过程Running With JRE 7 Or Later
启动tomcat所需环境

 else
    eval $_NOHUP "\"$_RUNJAVA\"" "\"$CATALINA_LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
      -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
      -classpath "\"$CLASSPATH\"" \
      -Dcatalina.base="\"$CATALINA_BASE\"" \
      -Dcatalina.home="\"$CATALINA_HOME\"" \
      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
      org.apache.catalina.startup.Bootstrap "$@" start \

后续不在赘述。重点在Server.properties中版本区别是否包含Netty的这个类,
本来我是想跟着dei一下bug的,实际是我没起来,版本又不兼容,中间穿插了需求,就不dei了skr~

目录
相关文章
|
1月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
128 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
4月前
|
XML Java 应用服务中间件
springboot定制嵌入式的servlet
SpringBoot允许定制嵌入式Servlet容器,如修改配置或更换默认的Tomcat。配置可通过`application.properties`设置`server.port`和`server.tomcat.*`属性。此外,可创建`EmbeddedServletContainerCustomizer` Bean来自定义容器,例如改变端口。要替换默认的Tomcat,需排除`spring-boot-starter-tomcat`依赖,并引入`spring-boot-starter-jetty`。
|
5月前
|
Java 应用服务中间件 容器
手写SpringBoot(二)之动态切换Servlet容器
我们在切换serlvet容器的时候,会将SpringBoot默认的tomcat jar包给排除掉,换上我们需要的jar包,比如jetty。
38 0
|
Java 应用服务中间件 容器
25 SpringBoot使用外置的Servlet容器
25 SpringBoot使用外置的Servlet容器
52 0
|
6月前
|
Java 应用服务中间件 Maven
框架的优点(SpringBoot VS Servlet)
框架的优点(SpringBoot VS Servlet)
|
6月前
|
前端开发 Java 容器
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
120 0
|
前端开发 Java 应用服务中间件
24 SpringBoot配置嵌入式Servlet容器
24 SpringBoot配置嵌入式Servlet容器
79 0
24 SpringBoot配置嵌入式Servlet容器
|
Java API Spring
在spring boot中添加servlet filter *Listener
在spring boot中添加servlet filter *Listener
在spring boot中添加servlet filter *Listener
|
消息中间件 负载均衡 Java
Springboot之---强大的Servlet(十 一)
如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
112 0
|
消息中间件 SQL 缓存
Springboot之---强大的Servlet(十)
如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
142 0