如何获取工厂Bean
参考:https://www.cnblogs.com/lifullmoon/p/14957595.html
跟springboot启动源码,是在对构造的应用上下文对象进行刷新的时候创建的web容器
![](https://img-blog.csdnimg.cn/img_convert/d2878dc9f27e773b8382d6c7fe12bc5a.png)
![](https://img-blog.csdnimg.cn/img_convert/eb5e93d018adbdf73e6d58871c262488.png)
![](https://img-blog.csdnimg.cn/img_convert/52e56050a487b076ececabd234c600ce.png)
这里的应用上下文的实现类是
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
主要看下这个类的父类 ServletWebServerApplicationContext ,他包含了一个WebServer 对象,这个就是web容器对象
![](https://img-blog.csdnimg.cn/img_convert/8395a88973d9ba56a1bba38f637bb6a2.png)
在看下是在哪里初始化这个对象的,是在对应用上下文调用刷新方法的时候,初始化的,看下源码:
![](https://img-blog.csdnimg.cn/img_convert/bdb71e60fb286ea963e8aa5262b11581.png)
继续跟
![](https://img-blog.csdnimg.cn/img_convert/f82e52f30cf38dcb94cc9de608aa8178.png)
继续
![](https://img-blog.csdnimg.cn/img_convert/829dd0ddabab41a25eb7d1982d7f7cac.png)
在这之前一直都是SpringApplication里的方法 , 下面代码就走到了AbstractApplicationContext里
![](https://img-blog.csdnimg.cn/img_convert/c15af3c23a3a580ace7cc07b7f282a92.png)
![](https://img-blog.csdnimg.cn/img_convert/1348d6eb93df15ff09f4d9df07f972a3.png)
![](https://img-blog.csdnimg.cn/img_convert/cbb8809f30124ce47ad06e956a46982a.png)
![](https://img-blog.csdnimg.cn/img_convert/14a30513abeb150c6b4d8ee088a1dc3e.png)
最终初始化WebServer的代码是在类AnnotationConfigServletWebServerApplicationContext父类
ServletWebServerApplicationContext 实现的~~
![](https://img-blog.csdnimg.cn/img_convert/9dd220bb9c2dc6e19aa1aa4f1a8ff740.png)
![](https://img-blog.csdnimg.cn/img_convert/d9067d32c3bb6164f15317da50b302be.png)
继续跟代码发现webServer 的初始化是由工厂Bean org.springframework.boot.web.servlet.server.ServletWebServerFactory实现的,并且Bean工厂实例在IOC容器已经存在了,是在哪里配置的这个工厂Bean实例的呢, 后面发现在springboot启动的时候默认加载的自动配置类里对这个工厂Bean的配置定义
![](https://img-blog.csdnimg.cn/img_convert/5f3bc0fd6e8cbe70d7b4b045a2b7f23e.png)
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
![](https://img-blog.csdnimg.cn/img_convert/931cd95b207011fea026949ba5d7a910.png)
ServletWebServerFactoryAutoConfiguration 这个自动配置类导入了一个配置项
ServletWebServerFactoryConfiguration.EmbeddedTomcat
![](https://img-blog.csdnimg.cn/img_convert/b66702be7de67d955de9f23e485aacba.png)
这个配置是实际工厂Bean 接口类 org.springframework.boot.web.servlet.server.ServletWebServerFactory
的实例org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
类图如下
![](https://img-blog.csdnimg.cn/img_convert/447912560106ba9a3fb689330615dc01.png)
通过工厂获取WebServer对象
![](https://img-blog.csdnimg.cn/img_convert/029dd1fe269c83ebdd97a1b58697206c.png)
之前跟源码发现,在通过工厂获取WebServer的方法有个入参是Servelet容器初始化器列表,用来初始化Servlet容器,这里实际上是初始化Servlet,Filter的地方
![](https://img-blog.csdnimg.cn/img_convert/0b6f191a5566b387716cb4c9d3bf9d04.png)
![](https://img-blog.csdnimg.cn/img_convert/ee48405799de95edca78b1bd7c517352.png)
注意org.springframework.boot.web.servlet.ServletContextInitializer是函数数接口
![](https://img-blog.csdnimg.cn/img_convert/fe6ca174551051f01b351f9bb846cdd2.png)
getSelfInitializer 这个方法其实是返回了一个实现了ServletContextInitializer 接口的匿名内部类的实例
还有这里this::selfInitialize ,是方法引用,lambda表达式的一种,使用lambda表达式会创建匿名方法, 有时候需要使用一个lambda表达式只调用一个已经存在的方法(没有其他逻辑), 所以有了方法引用(参考https://blog.csdn.net/zhoufanyang_china/article/details/87798829)