@SpringBootApplication
public class SpringBoot2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot2Application.class, args);
}
}
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}
@import({AutoConfigurationimportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class>[] exclude() default {};
String[] excludeName() default {};
}
public String[] selectimports(Annotationmetadata annotationmetadata) {
if (!this.isEnabled(annotationmetadata)) {
return NO_importS;
} else {
AutoConfigurationimportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationmetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
protected AutoConfigurationimportSelector.AutoConfigurationEntry getAutoConfigurationEntry(Annotationmetadata annotationmetadata) {
if (!this.isEnabled(annotationmetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationmetadata);
List configurations = this.getCandidateConfigurations(annotationmetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set exclusions = this.getExclusions(annotationmetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationimportEvents(configurations, exclusions);
return new AutoConfigurationimportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
protected ListgetCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) { List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in meta-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; } public static List loadFactoryNames(Class> factoryType, @Nullable ClassLoader classLoader) { ClassLoader classLoaderToUse = classLoader; if (classLoader == null) { classLoaderToUse = SpringFactoriesLoader.class.getClassLoader(); } String factoryTypeName = factoryType.getName(); return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList()); } public final class SpringFactoriesLoader { public static final String FACTORIES_RESOURCE_LOCATION = "meta-INF/spring.factories"; private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); static final Map >> cache = new ConcurrentReferenceHashMap(); private SpringFactoriesLoader() { } ... }
找到了自动配置类后会将这些自动配置类放入spring容器中,然后用他们来做自动配置。
简单分析一下ServletWebServerFactoryAutoConfiguration自动配置类。
@EnableConfigurationProperties({ServerProperties.class})的作用:开启自动配置属性,用ServerProperties类里面的成员变量关联配置文件中的属性,所有其他的和这个类相关的属性都可以在全局配置文件中定义。以后在这个配置类中添加新的bean组件时会自动为其与ServerProperties类成员变量相匹配的成员变量赋值(默认值),如果想修改新加入的bean成员变量值,就在配置文件里面修改ServerProperties类的成员变量值。
@EnableConfigurationProperties({ServerProperties.class})
@import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})
public class ServletWebServerFactoryAutoConfiguration {
public ServletWebServerFactoryAutoConfiguration() {
}
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties, ObjectProvider webListenerRegistrars) {
return new ServletWebServerFactoryCustomizer(serverProperties, (List)webListenerRegistrars.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnClass(
name = {"org.apache.catalina.startup.Tomcat"}
)
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
@Bean
@ConditionalOnMissingFilterBean({ForwardedHeaderFilter.class})
@ConditionalOnProperty(
value = {"server.forward-headers-strategy"},
havingValue = "framework"
)
public FilterRegistrationBean forwardedHeaderFilter() {
ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
FilterRegistrationBean registration = new FilterRegistrationBean(filter, new ServletRegistrationBean[0]);
registration.setDispatcherTypes(DispatcherType.REQUEST, new DispatcherType[]{DispatcherType.ASYNC, DispatcherType.ERROR});
registration.setOrder(-2147483648);
return registration;
}
public static class BeanPostProcessorsRegistrar implements importBeanDefinitionRegistrar, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
public BeanPostProcessorsRegistrar() {
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
}
}
public void registerBeanDefinitions(Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
if (this.beanFactory != null) {
this.registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", WebServerFactoryCustomizerBeanPostProcessor.class, WebServerFactoryCustomizerBeanPostProcessor::new);
this.registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", ErrorPageRegistrarBeanPostProcessor.class, ErrorPageRegistrarBeanPostProcessor::new);
}
}
private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class beanClass, Supplier instanceSupplier) {
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass, instanceSupplier);
beanDefinition.setSynthetic(true);
registry.registerBeanDefinition(name, beanDefinition);
}
}
}
}



