8、Servlet容器启动解析
// 这边就到了AutoConfigurationImportSelector类的方法中protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
// 判断是否支持自动配置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
// 这个attributes属性就是上图中显示的,用来过滤自动配置类的
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 下面分析这个方法,这个就是加载容器中的自动配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 去除重复的,方法就是放入set再放入list中
configurations = removeDuplicates(configurations);
// 去除掉应该被排除的
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 通过filter过滤,下面分析,过滤完发现只有22个了
configurations = filter(configurations, autoConfigurationMetadata);
// 发布一个事件,好像没有做啥关键的
fireAutoConfigurationImportEvents(configurations, exclusions);
// 将configurations封装成AutoConfigurationEntry返回
return new AutoConfigurationEntry(configurations, exclusions);
}
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
// 判断有没有配置这个属性,没有的话默认为true,
// String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
return true;
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { // getSpringFactoriesLoaderFactoryClass()返回EnableAutoConfiguration.class,那么这边就是获取容器中所有的字段配置类
// 见下图,默认总共有118个
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
return configurations;
}
private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) { long startTime = System.nanoTime();
String[] candidates = StringUtils.toStringArray(configurations);
boolean[] skip = new boolean[candidates.length];
boolean skipped = false;
for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
invokeAwareMethods(filter);
boolean[] match = filter.match(candidates, autoConfigurationMetadata);
for (int i = 0; i < match.length; i++) {
if (!match[i]) {
skip[i] = true;
candidates[i] = null;
skipped = true;
}
}
}
if (!skipped) {
return configurations;
}
List<String> result = new ArrayList<>(candidates.length);
for (int i = 0; i < candidates.length; i++) {
if (!skip[i]) {
result.add(candidates[i]);
}
}
return new ArrayList<>(result);
}
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
// 看一下这个过滤的逻辑,看下图它的实现类大概就知道它是怎样过滤了
return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
}
// 下面解释下1.3节提出的问题,tomcatServletWebServerFactory,这个bean定义什么时候被加载到容器中// filter之后的中有一个是org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
// 会Import一个这个
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
@Configuration class ServletWebServerFactoryConfiguration {
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
// 这边就会创建一个TomcatServletWebServerFactory
return new TomcatServletWebServerFactory();
}
}}
// 到此为止grouping.getImports方法分析完了,它是返回之前加载的22个自动配置类public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
// 下面先分析这个getImports方法
grouping.getImports().forEach(entry -> {
// 这边这个configurationClass获取的还是主配置类SpringbootApplication
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
// 调用processImports方法处理,这个方法之前已经分析过了
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
});
}
}
1.4、Web容器个性化配置解析
以上是 8、Servlet容器启动解析 的全部内容, 来源链接: utcz.com/z/513620.html