ApplicationContext在Spring Boot中是如何创建的?

一、ApplicationContext在Spring Boot中是如何创建的?

在这里插入图片描述

1. SpringApplication

ApplicationContextFactory有三个实现类,分别是AnnotationConfigReactiveWebServerApplicationContext.FactoryAnnotationConfigServletWebServerApplicationContext.Factory、DefaultApplicationContextFactory。

public ConfigurableApplicationContext run(String... args) {
		...
		// 创建ApplicationContext
		context = createApplicationContext();
		...
}

// 调用DefaultApplicationContextFactory的create
protected ConfigurableApplicationContext createApplicationContext() {
	return this.applicationContextFactory.create(this.webApplicationType);
}

2. DefaultApplicationContextFactory

下面有一点代码SpringFactoriesLoader.loadFactories(ApplicationContextFactory.class, getClass().getClassLoader()),是从org.springframework.bootMETA-INF/spring.factories寻找ApplicationContextFactory的实现类,也就是AnnotationConfigReactiveWebServerApplicationContext.Factory和AnnotationConfigServletWebServerApplicationContext.Factory。

@Override
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
	try {
		return getFromSpringFactories(webApplicationType, ApplicationContextFactory::create,
				AnnotationConfigApplicationContext::new);
	}
	catch (Exception ex) {
		throw new IllegalStateException("Unable create a default ApplicationContext instance, "
				+ "you may need a custom ApplicationContextFactory", ex);
	}
}

private <T> T getFromSpringFactories(WebApplicationType webApplicationType,
		BiFunction<ApplicationContextFactory, WebApplicationType, T> action, Supplier<T> defaultResult) {
	for (ApplicationContextFactory candidate : SpringFactoriesLoader.loadFactories(ApplicationContextFactory.class,
			getClass().getClassLoader())) {
		// 判断应用属于三种NONE、SERVLET、REACTIVE类型中的哪种类型,实例化对应类型的ApplicationContenxt。
		T result = action.apply(candidate, webApplicationType);
		if (result != null) {
			return result;
		}
	}
	// 创建AnnotationConfigApplicationContext
	return (defaultResult != null) ? defaultResult.get() : null;
}

二、AnnotationConfigServletWebServerApplicationContext构造函数做了什么事情?

public AnnotationConfigServletWebServerApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

1. AnnotatedBeanDefinitionReader

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);注册了以下6个bean。

  • org.springframework.context.annotation.internalConfigurationAnnotationProcessor
  • org.springframework.context.annotation.internalAutowiredAnnotationProcessor
  • org.springframework.context.annotation.internalCommonAnnotationProcessor
  • org.springframework.context.annotation.internalPersistenceAnnotationProcessor
  • org.springframework.context.event.internalEventListenerProcessor
  • org.springframework.context.event.internalEventListenerFactory

2. ClassPathBeanDefinitionScanner

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
	Environment environment, @Nullable ResourceLoader resourceLoader) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;

    if (useDefaultFilters) {
	    registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}

registerDefaultFilters 注册了以下的过滤器

protected void registerDefaultFilters() {
	this.includeFilters.add(new AnnotationTypeFilter(Component.class));
	// 这个ClassLoader是干什么的???
	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
		logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
	}
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
		logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}
  • Component.class
  • javax.annotation.ManagedBean
  • javax.inject.Named