springboot 修改了端口不生效_Spring Boot学习04_嵌入式Servlet容器自动配置原理

在Spring Boot的自动配置包下,找到web模块中的servlet文件夹下的ServletWebServerFactoryConfiguration类

一、嵌入式Servlet容器默认的配置原理

1、该类中有三个静态内部类(都是配置类):

EmbeddedUndertow、EmbeddedJetty、EmbeddedTomcat

这里拿EmbeddedTomcat来举例说明

@ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class})

判断classpath下有没有Servlet, Tomcat, UpgradeProtocol这三个类,也就是看maven有没有引入对应的依赖,如果引入了对应的依赖,下面的配置就生效。(上一篇文章SpringBoot切换嵌入式容器就是根据这里来的链接

v2-a108d1a9a9df8dc8fce4ef926db3cec4_b.jpg

2、@ConditionalOnMissingBean(
value = {ServletWebServerFactory.class},
search = SearchStrategy.CURRENT
)

如果容器中没有ServletWebServerFactory这个组件下面的配置就生效

点进ServletWebServerFactory看,该接口只有一个方法,前面只判断这个类型的组件有没有在容器中,而该类型又只有一个方法,说明最终Spring Boot会调用该接口实现类中的getWebServer方法。

v2-af8ef859b57aed00a48fff82d1032dc8_b.jpg

v2-8274f4d3f353159f34cf6901b0b050e4_b.jpg

3、查看ServletWebServerFactory接口的实现,有三个很面熟的实现类,就是上面ServletWebServerFactoryConfiguration类中要往容器中添加的组件

v2-2e938b77bd7ce739d0780015bd5d930e_b.jpg

v2-5dc7c14e50d3e6da523eba04f70eaa9d_b.jpg

4、进入TomcatServletWebServerFactory类中查看getWebServer方法

首先会创建一个Tomcat对象,给其设置连接器等一些配置

最终还会调用getTomcatWebServer方法

this.getTomcatWebServer(tomcat);

-->return new TomcatWebServer(tomcat, this.getPort() >= 0);

端口号默认是8080所以上面传过去的是true,进入TomcatWebServer的构造方法TomcatWebServer中,在构造方法中又调用了this.initialize();进入initialize方法,该方法就会启动tomcat。(所以这一切都是建立在创建好嵌入式Servlet容器之后)

v2-b94f08bb2764e71de2f26116c7ccba78_b.jpg

v2-817280b3fbe40cb008d5e4518c26c032_b.png

v2-730d1b0223f923f35aece578a21d2df3_b.jpg

v2-4c8df582fcba2e0352e87ab5ede601cc_b.jpg

二、修改SpringBoot初始化嵌入式Servlet容器的默认配置原理

上一篇文章(链接)中我们自己配置个WebServerFactoryCustomizer<ConfigurableWebServerFactory>组件就可以实现修改SpringBoot初始化嵌入式Servlet容器的默认配置了,下面开始说怎么修改其默认配置的。

在ServletWebServerFactoryAutoConfiguration类上面有

@EnableConfigurationProperties,@Import注解

v2-d1386adb06d7e9ccfaf06c6e4e7a2732_b.jpg

1、@EnableConfigurationProperties({ServerProperties.class})

把ServerProperties注册到容器中,并读取全局配置文件中的数据赋值给类中的属性。

只有一个有参构造,形参的值(serverProperties)会从容器中获取,最终交给ServletWebServerFactoryCustomizer类,进入ServletWebServerFactoryCustomizer类

该类也是WebServerFactoryCustomizer的子类

里面有个customize方法会把从容器中获取到的servlerProperties中的值拿出来然后一个一个的设置给factory,最后交给那个map。

v2-3683ccf2051ff70f809216125060b24a_b.png

v2-549c2c7372c2cce32a87c5f5a71efe42_b.jpg

2.1、通过@Import往容器中导入了一个BeanPostProcessorsRegistrar类,该类中的作用是

bean注册后置处理器:Bean初始化前后(创建好对象,还没赋值)执行初始化工作(容器中某个组件要创建bean,就会惊动后置处理器,容器中要创建bean这个才会触发,下面的方法才会被调用)

v2-2dc9e03f6f20db450c878c689edf13bc_b.jpg

2.2、进入BeanPostProcessorsRegistrar类查看registerBeanDefinitions方法(注册bean的定义),然后调用registerSyntheticBeanIfMissing方法

v2-f3237a76fe698689c08f747324600ea2_b.jpg

2.3、我们点进WebServerFactoryCustomizerBeanPostProcessor类中只需要看postProcessBeforeInitialization方法,在bean创建好之后,初始化之前的调用的方法,该方法首先会判断当前的bean如果为WebServerFactory类型(我们前面需要往容器中注册三个嵌入式Servlet容器就是该接口的实现类,所以当前这个bean就是嵌入式的Servlet容器),就调用postProcessBeforeInitialization方法

v2-5e6972624ac8c77bdfb8abcd125da353_b.png

2.4、进入postProcessBeforeInitialization方法,该方法会获得所有的定制器,然后遍历,调用每个定制器的customize方法,并把嵌入式的Servlet容器传进去。

上一篇文章(链接)中我们修改嵌入式的Servlet容器的配置也是往容器中添加一个WebServerFactoryCustomizer组件,并在其customize方法中修改配置。

在前面说到通过配置文件来修改配置也是在WebServerFactoryCustomizer的子类中重写了

customize方法,并在其customize方法中修改配置。

回到这里的postProcessBeforeInitialization方法,我们这里把嵌入式的Servlet容器传过去,调用所有定制器的customize方法,不就是调用的上面两种修改配置的重写后的customize方法吗,我们在重写后的customize方法中对参数进行设置值,就是对我们这里传过去的嵌入式Servlet容器设置值,最终通过全局配置文件中配置和往容器中添加一个WebServerFactoryCustomizer组件就可以达到修改嵌入式的Servlet容器的默认值了

v2-564a26c76f9b14a5a04db2b586e6d352_b.png

v2-31e6b76e737680d19bee4368d116debc_b.jpg
往容器中添加一个WebServerFactoryCustomizer组件

v2-07aedd4d341067b0142a508a5e491a68_b.jpg
前面说到的,经过一系列的逻辑最终全局配置文件中的值会在这里给嵌入式的Servlet容器进行赋值

v2-a2005659ad7b3965a794d7cee320268c_b.jpg

注:看完这一篇文章要结合下一篇文章来理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值