ApplicationContext
接口擴展了MessageSource
接口,於是提供了消息處理的功能(i18n或者國際化)。與HierarchicalMessageSource
一塊兒使用,它還可以處理嵌套的消息,這些是Spring提供的處理消息的基本接口。讓咱們快速瀏覽一下它所定義的方法:web
String getMessage(String code, Object[] args, String default, Locale loc):用來從
springMessageSource
獲取消息的基本方法。若是在指定的locale中沒有找到消息,則使用默認的消息。args中的參數將使用標準類庫中的MessageFormat
來做消息中替換值。
String getMessage(String code, Object[] args, Locale loc):本質上和上一個方法相同,其區別在:沒有指定默認值,若是沒找到消息,會拋出一個
編程NoSuchMessageException
異常。
String getMessage(MessageSourceResolvable resolvable, Locale locale)
:上面方法中所使用的屬性都封裝到一個MessageSourceResolvable
實現中,而本方法能夠指定MessageSourceResolvable
實現。windows
當一個ApplicationContext
被加載時,它會自動在context中查找已定義爲MessageSource
類型的bean。此bean的名稱須爲messageSource
。若是找到,那麼全部對上述方法的調用將被委託給該bean。不然ApplicationContext
會在其父類中查找是否含有同名的bean。若是有,就把它做爲MessageSource
。若是它最終沒有找到任何的消息源,一個空的StaticMessageSource
將會被實例化,使它可以接受上述方法的調用。app
Spring目前提供了兩個MessageSource
的實現:ResourceBundleMessageSource
和StaticMessageSource
。它們都繼承NestingMessageSource
以便可以處理嵌套的消息。StaticMessageSource
不多被使用,但能以編程的方式向消息源添加消息。ResourceBundleMessageSource
會用得更多一些,爲此提供了一下示例:測試
<beans> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>format</value> <value>exceptions</value> <value>windows</value> </list> </property> </bean> </beans>
這段配置假定在你的classpath中有三個資源文件(resource bundle),它們是format
,exceptions
和windows
。經過ResourceBundle,使用JDK中解析消息的標準方式,來處理任何解析消息的請求。出於示例的目的,假定上面的兩個資源文件的內容爲…ui
# in 'format.properties'message=Alligators rock!
# in 'exceptions.properties'argument.required=The '{0}' argument is required.
下面是測試代碼。由於ApplicationContext
實現也都實現了MessageSource
接口,因此能被轉型爲MessageSource
接口this
public static void main(String[] args) { MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); String message = resources.getMessage("message", null, "Default", null); System.out.println(message); }
上述程序的輸出結果將會是...spa
Alligators rock!
總而言之,咱們在'beans.xml'
的文件中(在classpath根目錄下)定義了一個messageSource
bean,經過它的basenames
屬性引用多個資源文件;而basenames
屬性值由list元素所指定的三個值傳入,它們以文件的形式存在並被放置在classpath的根目錄下(分別爲format.properties
,exceptions.properties
和windows.properties
)。code
再分析個例子,此次咱們將着眼於傳遞參數給查找的消息,這些參數將被轉換爲字符串並插入到已查找到的消息中的佔位符(譯註:資源文件中花括號裏的數字即爲佔位符)。
<beans> <!-- this MessageSource is being used in a web application --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="baseName" value="WEB-INF/test-messages"/> </bean> <!-- let's inject the above MessageSource into this POJO --> <bean id="example" class="com.foo.Example"> <property name="messages" ref="messageSource"/> </bean> </beans>
public class Example { private MessageSource messages; public void setMessages(MessageSource messages) { this.messages = messages; } public void execute() { String message = this.messages.getMessage("argument.required", new Object [] {"userDao"}, "Required", null); System.out.println(message); } }
調用execute()
方法的輸出結果是...
The 'userDao' argument is required.
對於國際化(i18n),Spring中不一樣的MessageResource
實現與JDK標準ResourceBundle中的locale解析規則同樣。好比在上面例子中定義的messageSource
bean,若是你想解析British (en-GB) locale的消息,那麼須要建立format_en_GB.properties
,exceptions_en_GB.properties
和windows_en_GB.properties
三個資源文件。
Locale解析一般由應用程序根據運行環境來指定。出於示例的目的,咱們對將要處理的(British)消息手工指定locale參數值。
# in 'exceptions_en_GB.properties'argument.required=Ebagum lad, the '{0}' argument is required, I say, required.
public static void main(final String[] args) { MessageSource resources = new ClassPathXmlApplicationContext("beans.xml"); String message = resources.getMessage("argument.required", new Object [] {"userDao"}, "Required", Locale.UK); System.out.println(message); }
上述程序運行時的輸出結果是...
Ebagum lad, the 'userDao' argument is required, I say, required.
MessageSourceAware
接口還能用於獲取任何已定義的MessageSource
引用。任何實現了MessageSourceAware
接口的bean將在建立和配置的時候與MessageSource
一同被注入。