EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自動配置?
```java
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@Import(BeanPostProcessorsRegistrar.class)
//導入BeanPostProcessorsRegistrar:Spring注解版;給容器中導入一些組件
//導入了EmbeddedServletContainerCustomizerBeanPostProcessor:
//后置處理器:bean初始化前后(創建完對象,還沒賦值賦值)執行初始化工作
public class EmbeddedServletContainerAutoConfiguration {
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })//判斷當前是否引入了Tomcat依賴;
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)//判斷當前容器沒有用戶自己定義EmbeddedServletContainerFactory:嵌入式的Servlet容器工廠;作用:創建嵌入式的Servlet容器
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class,
WebAppContext.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedJetty {
@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
return new JettyEmbeddedServletContainerFactory();
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow {
@Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
return new UndertowEmbeddedServletContainerFactory();
}
}
```
1)、EmbeddedServletContainerFactory(嵌入式Servlet容器工廠)
```java
public interface EmbeddedServletContainerFactory {
//獲取嵌入式的Servlet容器
EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers);
}
```

2)、EmbeddedServletContainer:(嵌入式的Servlet容器)

3)、以**TomcatEmbeddedServletContainerFactory**為例
```java
@Override
public EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers) {
//創建一個Tomcat
Tomcat tomcat = new Tomcat();
//配置Tomcat的基本環節
File baseDir = (this.baseDirectory != null ? this.baseDirectory
: createTempDir("tomcat"));
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
//將配置好的Tomcat傳入進去,返回一個EmbeddedServletContainer;并且啟動Tomcat服務器
return getTomcatEmbeddedServletContainer(tomcat);
}
```
4)、我們對嵌入式容器的配置修改是怎么生效?
```
ServerProperties、EmbeddedServletContainerCustomizer
```
**EmbeddedServletContainerCustomizer**:定制器幫我們修改了Servlet容器的配置?
怎么修改的原理?
5)、容器中導入了**EmbeddedServletContainerCustomizerBeanPostProcessor**
```java
//初始化之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
//如果當前初始化的是一個ConfigurableEmbeddedServletContainer類型的組件
if (bean instanceof ConfigurableEmbeddedServletContainer) {
//
postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);
}
return bean;
}
private void postProcessBeforeInitialization(
ConfigurableEmbeddedServletContainer bean) {
//獲取所有的定制器,調用每一個定制器的customize方法來給Servlet容器進行屬性賦值;
for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {
customizer.customize(bean);
}
}
private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
if (this.customizers == null) {
// Look up does not include the parent context
this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(
this.beanFactory
//從容器中獲取所有這葛類型的組件:EmbeddedServletContainerCustomizer
//定制Servlet容器,給容器中可以添加一個EmbeddedServletContainerCustomizer類型的組件
.getBeansOfType(EmbeddedServletContainerCustomizer.class,
false, false)
.values());
Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
this.customizers = Collections.unmodifiableList(this.customizers);
}
return this.customizers;
}
ServerProperties也是定制器
```
步驟:
1)、SpringBoot根據導入的依賴情況,給容器中添加相應的EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
2)、容器中某個組件要創建對象就會驚動后置處理器;EmbeddedServletContainerCustomizerBeanPostProcessor;
只要是嵌入式的Servlet容器工廠,后置處理器就工作;
3)、后置處理器,從容器中獲取所有的**EmbeddedServletContainerCustomizer**,調用定制器的定制方法
- Spring Boot 入門
- Spring Boot 簡介
- 微服務
- 環境準備
- MAVEN設置
- IDEA設置
- Spring Boot HelloWorld
- 創建一個maven工程;(jar)
- 導入spring boot相關的依賴
- 編寫一個主程序;啟動Spring Boot應用
- 編寫相關的Controller、Service
- 運行主程序測試
- 簡化部署
- Hello World探究
- POM文件
- 父項目
- 啟動器
- 主程序類,主入口類
- 使用Spring Initializer
- IDEA使用 Spring Initializer
- STS使用 Spring Starter Project快速創建項目
- 配置文件
- 配置文件
- YAML語法
- 基本語法
- 值的寫法
- 普通的值(數字,字符串,布爾)
- 對象、Map(屬性和值)(鍵值對)
- 數組(List、Set)
- 配置文件值注入
- 其他問題
- properties配置文件在idea中默認utf-8可能會亂碼
- @Value獲取值和@ConfigurationProperties獲取值比較
- 配置文件注入值數據校驗
- @PropertySource&@ImportResource&@Bean
- 配置文件占位符
- 隨機數
- 占位符獲取之前配置的值
- Profile
- 多Profile文件
- yml支持多文檔塊方式
- 激活指定profile
- 配置文件加載位置
- 外部配置加載順序
- 自動配置原理
- 自動配置原理
- 細節
- @Conditional派生注解(Spring注解版原生的@Conditional作用)
- 日志
- 日志框架
- SLF4j使用
- 如何在系統中使用SLF4j
- 遺留問題
- SpringBoot日志關系
- 日志使用
- 默認配置
- 指定配置
- 切換日志框架
- Web開發
- 簡介
- SpringBoot對靜態資源的映射規則
- 模板引擎
- 引入thymeleaf
- Thymeleaf使用
- 語法規則
- SpringMVC自動配置
- Spring MVC auto-configuration
- 擴展SpringMVC
- 全面接管SpringMVC
- 如何修改SpringBoot的默認配置
- RestfulCRUD
- 默認訪問首頁
- 國際化
- 登陸
- 攔截器進行登陸檢查
- CRUD-員工列表
- thymeleaf公共頁面元素抽取
- CRUD-員工添加
- CRUD-員工修改
- CRUD-員工刪除
- 錯誤處理機制
- SpringBoot默認的錯誤處理機制
- 如果定制錯誤響應
- 如何定制錯誤的頁面
- 如何定制錯誤的json數據
- 將我們的定制數據攜帶出去
- 配置嵌入式Servlet容器
- 如何定制和修改Servlet容器的相關配置
- 注冊Servlet三大組件【Servlet、Filter、Listener】
- 替換為其他嵌入式Servlet容器
- 嵌入式Servlet容器自動配置原理
- 嵌入式Servlet容器啟動原理
- 使用外置的Servlet容器
- 步驟
- 原理
- Docker
- 簡介
- 核心概念
- 安裝Docker
- 安裝linux虛擬機
- 在linux虛擬機上安裝docker
- Docker常用命令&操作
- 鏡像操作
- 容器操作
- 安裝MySQL示例
- SpringBoot與數據訪問
- JDBC
- 整合Druid數據源
- 整合MyBatis
- 注解版
- 配置文件版
- 整合SpringData JPA
- SpringData簡介
- 整合SpringData JPA
- 啟動配置原理
- 創建SpringApplication對象
- 運行run方法
- 事件監聽機制
- 自定義starter