以TomcatWebServerFactoryCustomizer为例:
public void customize(ConfigurableTomcatWebServerFactory factory) { ServerProperties properties = this.serverProperties; Tomcat tomcatProperties = properties.getTomcat(); PropertyMapper propertyMapper = PropertyMapper.get(); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getBasedir).whenNonNull().to(factory::setBaseDirectory); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull().as(Duration::getSeconds).as(Long::intValue).to(factory::setBackgroundProcessorDelay); this.customizeRemoteIpValve(factory); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive).to((maxThreads) -> { this.customizeMaxThreads(factory, tomcatProperties.getMaxThreads()); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive).to((minSpareThreads) -> { this.customizeMinThreads(factory, minSpareThreads); }); propertyMapper.from(this::determineMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes).when(this::isPositive).to((maxHttpHeaderSize) -> { this.customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull().asInt(DataSize::toBytes).to((maxSwallowSize) -> { this.customizeMaxSwallowSize(factory, maxSwallowSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxHttpPostSize).asInt(DataSize::toBytes).when((maxHttpPostSize) -> { return maxHttpPostSize != 0; }).to((maxHttpPostSize) -> { this.customizeMaxHttpPostSize(factory, maxHttpPostSize); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getAccesslog).when(Accesslog::isEnabled).to((enabled) -> { this.customizeAccessLog(factory); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getUriEncoding).whenNonNull().to(factory::setUriEncoding); properties.getClass(); propertyMapper.from(properties::getConnectionTimeout).whenNonNull().to((connectionTimeout) -> { this.customizeConnectionTimeout(factory, connectionTimeout); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getMaxConnections).when(this::isPositive).to((maxConnections) -> { this.customizeMaxConnections(factory, maxConnections); }); tomcatProperties.getClass(); propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive).to((acceptCount) -> { this.customizeAcceptCount(factory, acceptCount); }); this.customizeStaticResources(factory); this.customizeErrorReportValve(properties.getError(), factory); }
对嵌入式配置容器的修改是如何生效的:
1.ServerProperties,也是Servlet容器定制器
2.嵌入式Servlet容器定制器来修改
原理:BeanPostProcessorsRegistrar:给容器导入组件
BeanPostProcessor:后置处理器,在bean初始化(创建完对象,还没有赋值)时执行初始化工作
步骤:
1.SpringBoot根据导入的依赖情况,给容器中添加相应的嵌入式容器工厂
2.容器中某个组件要创建对象时,便会调用后置处理器,只要是嵌入式Servlet容器工厂,后置处理器就会工作.
3.后置处理器从容器中获取所有嵌入式容器处理器定制器,调用嵌入式容器处理器定制器中的方法对嵌入式容器处理器进行配置
1.SpringBoot应用启动run方法
2.SpringBoot刷新IOC容器refreshContext(创建IOC容器对象,并初始化容器,创建容器中的每一个组件.如果是web应用就创建AnnotationConfigEmbeddedWebApplicationContext,否则创建默认的AnnotationConfigApplicationContext)
3.刷新创建好的容器refresh(context)
4.此时调用重写的onRefresh()方法
5.web中IOC容器会创建嵌入式的Servlet容器:createEmbeddedServletContainer()
6.获取嵌入式的Servlet容器工厂,从IOC容器中获取嵌入式Servlet容器工厂组件,当该组件存在时,Tomcat嵌入式Servlet容器工厂创建对象,后置处理器就获取所有定制器来定制Tomcat嵌入式Servlet容器的配置
7.使用Tomcat嵌入式Servlet容器工厂获取嵌入式servlet容器
8.嵌入式的Servlet容器创建对象并启动Servlet容器,先启动嵌入式的Servlet容器,再将IOC容器中对象获取出来
至此,完成IOC容器启动创建嵌入式Servlet容器
嵌入式Servlet容器:
优点:简单,便捷
缺点:默认不支持jsp,优化定制复杂(使用定制器[ ServerProperties,自定义定制器],自己创建嵌入式Servlet容器的创建工厂)
外置的Servlet容器:外置安装Tomcat-应用war包的方式打包
步骤
1.创建一个war项目,配置好项目的Project Structure
2.将嵌入式的Tomcat指定为provided
3.编写一个SpringBootServletInitializer的子类,并调用configure方法,传入SpringBoot应用主程序
4.启动服务器就可以启动项目
原理:
jar包:执行SpringBoot主类的main方法,启动IOC容器,创建嵌入式Servlet容器
war包:启动服务器,服务器启动SpringBoot应用(SpringBootServletInitializer),然后才能启动IOC容器