该文转载自:http://www.yunkebiji.com/noteview/1204307482538082305.html
版权由原文作者所有,不得转载
这一节课我们来说一说嵌入式Servlet容器自动配置原理
前面我们都知道怎么去配置容器参数,切换容器,但是我们不知道springboot自动配置了哪些东西,究竟原理是怎么样的,这一片笔记就告诉你springboot嵌入是Servlet容器自动配置的原理。
我们先找到springboot自动配置包:
找到EmbeddedServletContainerAutoConfiguration这个类,这个类就是容器的自动配置类
这个类里面会注入一个EmbeddedServletContainerFactory,看名字就知道是一个容器工厂,工厂是干嘛用的,当然就是创建容器的。
然而EmbeddedServletContainerFactory仅仅只是一个接口,具体的实现有三个,就是TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory,UndertowEmbeddedServletContainerFactory,看到名字大家就知道了,这三个容器工厂会创建不同的容器,而从上图源码可以看出,默认是new了一个TomcatEmbeddedServletContainerFactory,这也就是为什么springboot默认是tomcat了。
那么我们以TomcatEmbeddedServletContainerFactory为例继续追踪源码
源码可以看出就是new了一个Tomcat,并配置了一些参数,在调用TomcatEmbeddedServletContainerFactory的getTomcatEmbeddedServletContainer()方法。具体就是去new了一个TomcatEmbeddedServletContainer,由下图可以看到它的构造方法,是传入了一个tomcat进去,并且配置autoStart(是否自动启动);
通过下图也可以看出,tomcat在这个时候就已经start(),开始启动了。
上面看源码我们知道了容器切换原理,但是我们仍然不知道我们给容器的配置是怎么生效的,我们通过前面的课程都知道配置容器参数有两种方式,这里再次粘贴出来,唤醒大家的记忆:
1、修改和server有关的配置(ServerProperties【也是EmbeddedServletContainerCustomizer】);
server.port=8081
server.context-path=/crud
server.tomcat.uri-encoding=UTF-8
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx
2、编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;来修改Servlet容器的配置
@Bean //一定要将这个定制器加入到容器中
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new EmbeddedServletContainerCustomizer() {
//定制嵌入式的Servlet容器相关的规则
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(8083);
}
};
}
第一种方式最终原理还是通过第二种方式创建EmbeddedServletContainerCustomizer配置的。
我们现在就需要知道在EmbeddedServletContainerCustomizer中配置的参数到底在哪里配置到容器中使用的,我们需要回到最开始的自动配置类,如下图,标记处,导入了一个后置处理器,最主要要的作用就是注入EmbeddedServletContainerCustomizerBeanPostProcessor这个后置处理器,所谓后置处理器不明白的可以在云课笔记查看spring的相关视频教程,总的来说就是在bean刚创建完之后,但是还没有赋值时,执行一些操作。
我们追踪EmbeddedServletContainerCustomizerBeanPostProcessor中的postProcessBeforeInitialization方法,可以看出作用就是找到所有的customizer,去执行customize方法,这个方法就会为容器配上所有的参数。
总结一下: