diff --git a/docs/Spring/clazz/Spring-MessageSource.md b/docs/Spring/clazz/Spring-MessageSource.md new file mode 100644 index 0000000..b3b3c95 --- /dev/null +++ b/docs/Spring/clazz/Spring-MessageSource.md @@ -0,0 +1,210 @@ +# Spring MessageSource +- Author: [HuiFer](https://github.com/huifer) +- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read) + +## 初始化入口 +- `org.springframework.context.support.AbstractApplicationContext.refresh`方法有`initMessageSource()`方法进行了`MessageSource`初始化 + + + +```java + protected void initMessageSource() { + ConfigurableListableBeanFactory beanFactory = getBeanFactory(); + // 判断是否含有 messageSource + if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { + // 读取xml配置文件中 id="messageSource"的数据 + 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; + // 注册单例对象 + beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); + if (logger.isTraceEnabled()) { + logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); + } + } + } + +``` + + + + + +读取xml配置文件 + +![image-20200119141937915](/images/spring/image-20200119141937915.png) + + + + + + + +## getMessage + +- `org.springframework.context.support.AbstractApplicationContext#getMessage(java.lang.String, java.lang.Object[], java.util.Locale)` + +```java + @Override + public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException { + return getMessageSource().getMessage(code, args, locale); + } + +``` + +- `org.springframework.context.support.AbstractMessageSource#getMessage(java.lang.String, java.lang.Object[], java.util.Locale)` + + ```java + @Override + public final String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException { + // 获取对应的信息 + String msg = getMessageInternal(code, args, locale); + if (msg != null) { + return msg; + } + // 默认信息 null + String fallback = getDefaultMessage(code); + if (fallback != null) { + return fallback; + } + throw new NoSuchMessageException(code, locale); + } + + ``` + + - 两个方法 + + 1. `org.springframework.context.support.AbstractMessageSource#getDefaultMessage(java.lang.String)` + + ```java + @Nullable + protected String getDefaultMessage(String code) { + // 判断是否使用默认值 + if (isUseCodeAsDefaultMessage()) { + return code; + } + return null; + } + + ``` + + - 返回code本身或者`null` + + 2. `org.springframework.context.support.AbstractMessageSource#getMessageInternal` + + ```JAVA + @Nullable + protected String getMessageInternal(@Nullable String code, @Nullable Object[] args, @Nullable Locale locale) { + if (code == null) { + return null; + } + if (locale == null) { + // 获取语言默认值 + locale = Locale.getDefault(); + } + Object[] argsToUse = args; + + if (!isAlwaysUseMessageFormat() && ObjectUtils.isEmpty(args)) { + // Optimized resolution: no arguments to apply, + // therefore no MessageFormat needs to be involved. + // Note that the default implementation still uses MessageFormat; + // this can be overridden in specific subclasses. + String message = resolveCodeWithoutArguments(code, locale); + if (message != null) { + return message; + } + } + + else { + // Resolve arguments eagerly, for the case where the message + // is defined in a parent MessageSource but resolvable arguments + // are defined in the child MessageSource. + argsToUse = resolveArguments(args, locale); + + MessageFormat messageFormat = resolveCode(code, locale); + if (messageFormat != null) { + synchronized (messageFormat) { + return messageFormat.format(argsToUse); + } + } + } + + // Check locale-independent common messages for the given message code. + Properties commonMessages = getCommonMessages(); + if (commonMessages != null) { + String commonMessage = commonMessages.getProperty(code); + if (commonMessage != null) { + return formatMessage(commonMessage, args, locale); + } + } + + // Not found -> check parent, if any. + return getMessageFromParent(code, argsToUse, locale); + } + + ``` + + + +- `org.springframework.context.support.ResourceBundleMessageSource#resolveCodeWithoutArguments` + + ```JAVA + @Override + protected String resolveCodeWithoutArguments(String code, Locale locale) { + Set basenames = getBasenameSet(); + for (String basename : basenames) { + // 加载 basename + ResourceBundle bundle = getResourceBundle(basename, locale); + if (bundle != null) { + // 从basename对应的文件中获取对应的值 + String result = getStringOrNull(bundle, code); + if (result != null) { + return result; + } + } + } + return null; + } + + ``` + + + + + + + +![image-20200119143046066](/images/spring/image-20200119143046066.png) + + + +- 加载后截图 + + 获取方法`String result = getStringOrNull(bundle, code);`就是map获取 + +![image-20200119144019171](/images/spring/image-20200119144019171.png) + + + + + +- 没有配置文件的情况 + + ![image-20200119145138205](/images/spring/image-20200119145138205.png) \ No newline at end of file diff --git a/images/spring/image-20200119141937915.png b/images/spring/image-20200119141937915.png new file mode 100644 index 0000000..1eeef7a Binary files /dev/null and b/images/spring/image-20200119141937915.png differ diff --git a/images/spring/image-20200119143046066.png b/images/spring/image-20200119143046066.png new file mode 100644 index 0000000..eaeb625 Binary files /dev/null and b/images/spring/image-20200119143046066.png differ diff --git a/images/spring/image-20200119144019171.png b/images/spring/image-20200119144019171.png new file mode 100644 index 0000000..447e512 Binary files /dev/null and b/images/spring/image-20200119144019171.png differ diff --git a/images/spring/image-20200119145138205.png b/images/spring/image-20200119145138205.png new file mode 100644 index 0000000..0c27aeb Binary files /dev/null and b/images/spring/image-20200119145138205.png differ