②消息參數接口:MessageSourceResolvable
②消息參數:DefaultMessageSourceResolvable、FieldError、ObjectError
1、MessageSource:
- String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
- String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
- String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
- void setParentMessageSource(MessageSource parent);
- MessageSource getParentMessageSource();
- public String[] getCodes();
- public Object[] getArguments();
- public String getDefaultMessage();
②提供MessageSourceResolvable接口,方便消息的使用。取得消息時不需要自己組織多個參數,而是直接將一個MessageSourceResolvable的實現傳入即可。
③MessageSourceResolvable接口爲什麼不提供getLocal()操作?國際化應該是與業務實現無關,不應該是由業務實現去考慮。最好通過配置,或其他方法自動取得。
1、AbstractMessageSource
②提供的屬性:
- private boolean useCodeAsDefaultMessage = false;
- private boolean alwaysUseMessageFormat = false;
③實現操作祥解:
- void setParentMessageSource(MessageSource parent);
- MessageSource getParentMessageSource();
- String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
- String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
- String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
⑤getMessageInternal()方法的實現:
- 無消息參數,且alwaysUseMessageFormat爲false時,調用resolveCodeWithoutArguments()方法直接取得消息。其實在resolveCodeWithoutArguments()方法的實現中還是使用MessageFormat,所以Spring建議在子類中覆蓋resolveCodeWithoutArguments()方法。
- 否則,先調用resolveArguments()方法將參數中的MessageSourceResolvable實例轉化爲對應的消息,然後調用resolveCode()取得MessageFormat,之後使用MessageFormat處理消息。
- 當沒有找到消息時,調用getMessageFromParent()方法,從父MessageSource中查找消息。
考慮到多數DefaultMessage都是一些同樣錯誤消息,所以Spring使用一個HashMap—cachedMessageFormats緩存了DefaultMessage的MessageFormat。
繼承AbstractMessageSource類,提供了最簡單的MessageSource的實現。提供了兩個操作:
- addMessage()將消息編號和對應的MessageFormat保存於一個HashMap中。
- resolveCode()根據消息編號和Local從HashMap中取得對應的MessageFormat。
繼承AbstractMessageSource類,實現了BeanClassLoaderAware接口,提供了一種使用Resource Bundle的Message Source的實現。
- basenames屬性
resolveCodeWithoutArguments()覆蓋了父類的對應方法,實現了直接從配置文件讀取message並直接返回,不使用MessageFormat。
- resolveCode()
- ResourceBundleMessageSource中的緩存實現。
- ResourceBundle緩存
- MessageFormat緩存
通過自己實現的PropertiesPersister和PropertiesHolder,跳過ResoureBundle的緩存機制,實現一個可以刷新的MessageSoruce。
實現了MessageSource接口,將getMessage的調用轉發給實際的MessageSource的實現。
2.MessageSourceAware
當Spring的IOC容器發現實現了此接口的實例,就會將ApplicationContext注入到此實例中。