SpringBoot 源码阅读(7):prepareContext

prepareContext

private void prepareContext(ConfigurableApplicationContext context,
		ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
		ApplicationArguments applicationArguments, Banner printedBanner) {
	
	//设置环境	
	context.setEnvironment(environment);
	//配置上下文
	postProcessApplicationContext(context);
	//初始化上下文
	applyInitializers(context);
	//上下文准备好,触发相应的监听器
	listeners.contextPrepared(context);
	
	//日志输出
	if (this.logStartupInfo) {
		logStartupInfo(context.getParent() == null);
		logStartupProfileInfo(context);
	}
	
	//获得bean工厂,注册一些单例
	// Add boot specific singleton beans
	ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();	
	beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
	if (printedBanner != null) {
		beanFactory.registerSingleton("springBootBanner", printedBanner);
	}
	
	//设置是否允许bean定义覆盖
	if (beanFactory instanceof DefaultListableBeanFactory) {
		((DefaultListableBeanFactory) beanFactory)
				.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
	}

	//加载资源
	// Load the sources
	Set<Object> sources = getAllSources();
	Assert.notEmpty(sources, "Sources must not be empty");
	load(context, sources.toArray(new Object[0]));
	
	//触发监听器
	listeners.contextLoaded(context);
}

整体分为9步:

  1. 设置环境
  2. 对上下文进行了如下配置(虽然带个postProcess,但没有应用后处理器bean):
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {

	//注册bean名称生成器
	if (this.beanNameGenerator != null) {
		context.getBeanFactory().registerSingleton(
				AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
				this.beanNameGenerator);
	}
	if (this.resourceLoader != null) {
		//设置资源加载器
		if (context instanceof GenericApplicationContext) {
			((GenericApplicationContext) context)
					.setResourceLoader(this.resourceLoader);
		}
		//设置类加载器
		if (context instanceof DefaultResourceLoader) {
			((DefaultResourceLoader) context)
					.setClassLoader(this.resourceLoader.getClassLoader());
		}
	}
	
	//设置转换服务
	if (this.addConversionService) {
		context.getBeanFactory().setConversionService(
				ApplicationConversionService.getSharedInstance());
	}
}
  1. 初始化上下文:
    调用各个ApplicationContextInitializer初始化上下文:
protected void applyInitializers(ConfigurableApplicationContext context) {
	for (ApplicationContextInitializer initializer : getInitializers()) {
	
		//判断上下文是否可被该Initializer初始化
		Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(
				initializer.getClass(), ApplicationContextInitializer.class);
		Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
		
		initializer.initialize(context);
	}
}
  1. 上下文准备好,触发相应的监听器:
public void contextPrepared(ConfigurableApplicationContext context) {
	for (SpringApplicationRunListener listener : this.listeners) {
		listener.contextPrepared(context);
	}
}
  1. 日志输出

  2. 注册一些单例

  3. 设置是否允许bean定义 覆盖

  4. 加载资源
    这一步注册了MainApplication的bean定义。

public Set<Object> getAllSources() {
	Set<Object> allSources = new LinkedHashSet<>();
	if (!CollectionUtils.isEmpty(this.primarySources)) {
		allSources.addAll(this.primarySources);
	}
	if (!CollectionUtils.isEmpty(this.sources)) {
		allSources.addAll(this.sources);
	}
	return Collections.unmodifiableSet(allSources);
}

primarySources即我们的MainApplication,加载资源:

protected void load(ApplicationContext context, Object[] sources) {
	if (logger.isDebugEnabled()) {
		logger.debug(
				"Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
	}

	//bean定义加载器
	BeanDefinitionLoader loader = createBeanDefinitionLoader(
			getBeanDefinitionRegistry(context), sources);
	
	//bean名称生成器		
	if (this.beanNameGenerator != null) {
		loader.setBeanNameGenerator(this.beanNameGenerator);
	}
	
	//资源加载器
	if (this.resourceLoader != null) {
		loader.setResourceLoader(this.resourceLoader);
	}
	
	//设置环境
	if (this.environment != null) {
		loader.setEnvironment(this.environment);
	}
	
	//加载bean定义
	loader.load();
}

加载每个资源:

public int load() {
	int count = 0;
	for (Object source : this.sources) {
		count += load(source);
	}
	return count;
}

primarySources为类:

private int load(Object source) {
	Assert.notNull(source, "Source must not be null");
	if (source instanceof Class<?>) {
		return load((Class<?>) source);
	}
	if (source instanceof Resource) {
		return load((Resource) source);
	}
	if (source instanceof Package) {
		return load((Package) source);
	}
	if (source instanceof CharSequence) {
		return load((CharSequence) source);
	}
	throw new IllegalArgumentException("Invalid source type " + source.getClass());
}

MainAppliacation注解@SpringBootApplication含有@SpringBootConfiguration
@SpringBootConfiguration含有@Configuration,
即为组件,见博客

private int load(Class<?> source) {
	if (isGroovyPresent()
			&& GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
		// Any GroovyLoaders added in beans{} DSL can contribute beans here
		GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source,
				GroovyBeanDefinitionSource.class);
		load(loader);
	}
	if (isComponent(source)) {
		this.annotatedReader.register(source);
		return 1;
	}
	return 0;
}
private boolean isComponent(Class<?> type) {
	// This has to be a bit of a guess. The only way to be sure that this type is
	// eligible is to make a bean definition out of it and try to instantiate it.
	if (AnnotationUtils.findAnnotation(type, Component.class) != null) {
		return true;
	}
	// Nested anonymous classes are not eligible for registration, nor are groovy
	// closures
	if (type.getName().matches(".*\\$_.*closure.*") || type.isAnonymousClass()
			|| type.getConstructors() == null || type.getConstructors().length == 0) {
		return false;
	}
	return true;
}

this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);

注册MainAppliacation bean定义:

this.annotatedReader.register(source);
  1. 上下文加载完成,触发监听器
public void contextLoaded(ConfigurableApplicationContext context) {
	for (SpringApplicationRunListener listener : this.listeners) {
		listener.contextLoaded(context);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值