Spring中refresh分析之initMessageSource方法详解

关联博文:
AbstractApplicationContext中refresh方法详解
Spring中refresh分析之prepareRefresh方法详解
Spring中refresh分析之obtainFreshBeanFactory方法详解
Spring中refresh分析之prepareBeanFactory方法详解
Spring中refresh分析之postProcessBeanFactory方法详解
Spring中refresh分析之invokeBeanFactoryPostProcessors方法详解
Spring中refresh分析之registerBeanPostProcessors方法详解
Spring中refresh分析之initMessageSource方法详解
Spring中refresh分析之initApplicationEventMulticaster方法详解
Spring中refresh分析之onRefresh方法详解
Spring中refresh分析之registerListeners方法详解
Spring中refresh分析之finishBeanFactoryInitialization方法详解
Spring中refresh分析之finishRefresh方法详解

接上文Spring中refresh分析之registerBeanPostProcessors方法详解我们分析过registerBeanPostProcessors后,本文分析initMessageSource方法。

MessageSource 是用来处理国际化的,该方法将会初始化MessageSource并尝试设置parentMessageSource,然后作为单例bean注册到容器中。通常注册是DelegatingMessageSource 实例。

AbstractApplicationContext的initMessageSource方法如下所示。

protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// messageSource
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// Make MessageSource aware of parent MessageSource.
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				// Only set parent context as parent MessageSource if no parent MessageSource
				// registered already.
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Using MessageSource [" + this.messageSource + "]");
		}
	}
	else {
		// Use empty MessageSource to be able to accept getMessage calls.
		//实例化DelegatingMessageSource
		DelegatingMessageSource dms = new DelegatingMessageSource();
		//设置父消息源
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		//注册单例bean
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
		}
	}
}

getInternalParentMessageSource

AbstractApplicationContextgetInternalParentMessageSource方法如下所示,如果父上下文也是AbstractApplicationContext,则返回父上下文的内部消息源;否则,返回父上下文本身。

@Nullable
protected MessageSource getInternalParentMessageSource() {
	return (getParent() instanceof AbstractApplicationContext ?
			((AbstractApplicationContext) getParent()).messageSource : getParent());
}

DelegatingMessageSource如下所示,内部维护了一个MessageSource parentMessageSource
在这里插入图片描述
HierarchicalMessageSource主要提供了设置父消息的操作。此接口用于当消息源不能解决给定消息时,尝试使用父消息源解决消息,即层级解决消息。

MessageSourceSupport内部主要成员为消息格式缓存Map<String, Map<Locale, MessageFormat>> messageFormatsPerMessage = new HashMap<>()用于存储消息的消息格式, 以及是否应用消息格式规则,解析没有参数的消息标志alwaysUseMessageFormat。此消息源实现基础类主要提供了根据给定的消息,消息参数和本地化渲染消息操作,即使用参数替代默认消息中的占位符。

DelegatingMessageSource内部有一父消息源,获取编码消息操作直接委托给父类数据源,如果没有父消息源,同时有默认消息,则使用消息参数 渲染默认消息,并返回。如果没有父消息可用且没有默认消息源,不会解决任何消息,抛出异常。代理消息源用于上下文没有定义消息源情况下,AbstractApplicationContext 使用 DelegatingMessageSource为消息源的占位符,此代理消息源不能被应用直接使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值