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

回到顶部