Home [Spring] 1.15.1. Internationalization using MessageSource
Post
Cancel

[Spring] 1.15.1. Internationalization using MessageSource

1.15.1. Internationalization using MessageSource

The ApplicationContext interface extends an interface called MessageSource and, therefore, provides internationalization (“i18n”) functionality. Spring also provides the HierarchicalMessageSource interface, which can resolve messages hierarchically. Together, these interfaces provide the foundation upon which Spring effects message resolution. The methods defined on these interfaces include:

  • ApplicationContext 인터페이스는 MessageSource라고 불리는 인터페이스를 확장하므로 국제화(“i18n”) 기능을 제공한다.
  • 스프링은 또한 메시지를 계층적으로 해결(resolve)할 수 있는 계층적 MessageSource (HierarchicalMessageSource) 인터페이스를 제공한다.
  • 이 인터페이스들은 스프링이 message resolution에 영향을 미치는 기초를 제공한다.
  • 이러한 인터페이스에 정의된 방법에는 다음이 포함된다.

    String getMessage(String code, Object[] args, String default, Locale loc): The basic method used to retrieve a message from the MessageSource. When no message is found for the specified locale, the default message is used. Any arguments passed in become replacement values, using the MessageFormat functionality provided by the standard library.

    • String getMessage(String code, Object[] args, String default, Locale loc):
    • MessageSource에서 메시지를 검색하는 데 사용되는 기본 방법.
    • 지정된 locale에 대한 메시지를 찾을 수 없는 경우 기본 메시지가 사용된다.
    • 전달된 인수는 표준 라이브러리에서 제공하는 MessageFormat 기능을 사용하여 대체 값이 된다.

    String getMessage(String code, Object[] args, Locale loc): Essentially the same as the previous method but with one difference: No default message can be specified. If the message cannot be found, a NoSuchMessageException is thrown.

    • String getMessage(String code, Object[] args, Locale loc):
    • 기본적으로 이전 방법과 동일하지만 한 가지 차이점이 있음: 기본 메시지를 지정할 수 없다.
    • 메시지를 찾을 수 없는 경우
      • throw NoSuchMessageException

    String getMessage(MessageSourceResolvable resolvable, Locale locale): All properties used in the preceding methods are also wrapped in a class named MessageSourceResolvable, which you can use with this method.

    • String getMessage(MessageSourceResolvable resolvable, Locale locale):
    • 앞의 방법에 사용된 모든 properties도 MessageSourceResolable이라는 클래스로 포장되어 있는데, 이 방법으로도 사용할 수 있다.

When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name messageSource. If such a bean is found, all calls to the preceding methods are delegated to the message source. If no message source is found, the ApplicationContext attempts to find a parent containing a bean with the same name. If it does, it uses that bean as the MessageSource. If the ApplicationContext cannot find any source for messages, an empty DelegatingMessageSource is instantiated in order to be able to accept calls to the methods defined above.

  • ApplicationContext가 로드되면 컨텍스트에 정의된 MessageSource bean을 자동으로 검색한다.
  • bean에는 messageSource라는 이름이 있어야 한다.
  • 그러한 bean이 발견되면, 앞의 방법에 대한 모든 호출은 메시지 소스에 위임된다.
  • 메시지 소스를 찾을 수 없는 경우 ApplicationContext는 동일한 이름의 bean을 포함하는 상위 항목을 찾으려고 시도한다.
  • 만약 그렇다면, 그것은 MessageSource로 그 bean을 사용한다.
  • ApplicationContext가 메시지의 소스를 찾을 수 없는 경우, 위에서 정의한 메서드에 대한 호출을 수락할 수 있도록 빈 위임 MessageSource (DelegatingMessageSource)가 인스턴스화된다.

Spring provides two MessageSource implementations, ResourceBundleMessageSource and StaticMessageSource. Both implement HierarchicalMessageSource in order to do nested messaging. The StaticMessageSource is rarely used but provides programmatic ways to add messages to the source. The following example shows ResourceBundleMessageSource:

  • Spring은 두 가지 MessageSource 구현인 ResourceBundleMessageSourceStaticMessageSource를 제공한다.
  • 둘 다 중첩된 메시지를 수행하기 위해 계층적 메시지 소스(HierarchicalMessageSource)를 구현한다.
  • StaticMessageSource는 거의 사용되지 않지만 소스에 메시지를 추가하는 프로그램적인 방법을 제공한다.
  • 다음 예제는 ResourceBundleMessageSource를 보여준다.
1
2
3
4
5
6
7
8
9
10
11
12
<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>

The example assumes that you have three resource bundles called format, exceptions and windows defined in your classpath. Any request to resolve a message is handled in the JDK-standard way of resolving messages through ResourceBundle objects. For the purposes of the example, assume the contents of two of the above resource bundle files are as follows:

  • 이 예에서는 사용자가 클래스 경로에 정의된 format, exceptionswindows이라는 세 가지 리소스 번들을 가지고 있다고 가정한다.
  • 메시지 해결(resolve) 요청은 ResourceBundle 개체를 통해 메시지를 해결하는 JDK 표준 방식으로 처리된다.
  • 예를 들어 위의 리소스 번들 파일 중 두 개의 내용이 다음과 같다고 가정하자.
1
2
# in format.properties
message=Alligators rock!
1
2
# in exceptions.properties
argument.required=The {0} argument is required.

The next example shows a program to execute the MessageSource functionality. Remember that all ApplicationContext implementations are also MessageSource implementations and so can be cast to the MessageSource interface.

  • 다음 예는 MessageSource 기능을 실행하는 프로그램을 보여준다.
  • 모든 ApplicationContext 구현도 MessageSource 구현이므로 MessageSource 인터페이스에 캐스팅할 수 있다는 점을 기억하자.
1
2
3
4
5
fun main() {
    val resources = ClassPathXmlApplicationContext("beans.xml")
    val message = resources.getMessage("message", null, "Default", Locale.ENGLISH)
    println(message)
}

The resulting output from the above program is as follows:

1
Alligators rock!

To summarize, the MessageSource is defined in a file called beans.xml, which exists at the root of your classpath. The messageSource bean definition refers to a number of resource bundles through its basenames property. The three files that are passed in the list to the basenames property exist as files at the root of your classpath and are called format.properties, exceptions.properties, and windows.properties, respectively.

  • 요약하자면 MessageSource는 classpath의 루트에 존재하는 beans.xml이라는 파일에 정의되어 있다.
  • messageSource bean 정의는 basenames 속성을 통해 많은 리소스 번들을 가리킨다.
  • 목록에 basenames 속성으로 전달되는 세 개의 파일은 클래스 경로의 루트에 파일로 존재하며 각각 format.properties, exceptions.properties, window.properties라고 불린다.

The next example shows arguments passed to the message lookup. These arguments are converted into String objects and inserted into placeholders in the lookup message.

  • 다음 예는 메시지 검색에 전달된 인수를 보여준다.
  • 이러한 인수는 문자열 개체로 변환되어 조회 메시지의 placeholders에 삽입된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<beans>

    <!-- this MessageSource is being used in a web application -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="exceptions"/>
    </bean>

    <!-- lets inject the above MessageSource into this POJO -->
    <bean id="example" class="com.something.Example">
        <property name="messages" ref="messageSource"/>
    </bean>

</beans>
1
2
3
4
5
6
7
8
9
10
class Example {

    lateinit var messages: MessageSource

    fun execute() {
        val message = messages.getMessage("argument.required",
                arrayOf("userDao"), "Required", Locale.ENGLISH)
        println(message)
    }
}

The resulting output from the invocation of the execute() method is as follows:

1
The userDao argument is required.

With regard to internationalization (“i18n”), Spring’s various MessageSource implementations follow the same locale resolution and fallback rules as the standard JDK ResourceBundle. In short, and continuing with the example messageSource defined previously, if you want to resolve messages against the British (en-GB) locale, you would create files called format_en_GB.properties, exceptions_en_GB.properties, and windows_en_GB.properties, respectively.

  • 국제화(“i18n”)와 관련하여 Spring의 다양한 MessageSource 구현은 표준 JDK ResourceBundle과 동일한 로케일 해상도 및 예비 규칙을 따른다.
  • 간단히 말해서 이전에 정의한 messageSource를 계속하여, 영국어(en-GB) 로케일에 대해 메시지를 해결하려면 format_en_GB.properties, exce_en_GB.propertieswindows_en_GB.properties라는 파일을 각각 생성하십시오.

Typically, locale resolution is managed by the surrounding environment of the application. In the following example, the locale against which (British) messages are resolved is specified manually:

  • 일반적으로 로케일 resolution는 애플리케이션의 주변 환경에 의해 관리된다.
  • 다음 예에서 (영국) 메시지가 확인되는 로케일은 수동으로 지정된다.
1
2
# in exceptions_en_GB.properties
argument.required=Ebagum lad, the ''{0}'' argument is required, I say, required.
1
2
3
4
5
6
fun main() {
    val resources = ClassPathXmlApplicationContext("beans.xml")
    val message = resources.getMessage("argument.required",
            arrayOf("userDao"), "Required", Locale.UK)
    println(message)
}

The resulting output from the running of the above program is as follows:

1
Ebagum lad, the 'userDao' argument is required, I say, required.

You can also use the MessageSourceAware interface to acquire a reference to any MessageSource that has been defined. Any bean that is defined in an ApplicationContext that implements the MessageSourceAware interface is injected with the application context’s MessageSource when the bean is created and configured.

  • MessageSourceAware 인터페이스를 사용하여 정의된 모든 MessageSource에 대한 참조를 획득할 수도 있다.
  • MessageSourceAware 인터페이스를 구현하는 ApplicationContext에 정의된 모든 bean은 bean이 생성되고 구성될 때 애플리케이션 컨텍스트의 MessageSource와 함께 주입된다.

As an alternative to ResourceBundleMessageSource, Spring provides a ReloadableResourceBundleMessageSource class. This variant supports the same bundle file format but is more flexible than the standard JDK based ResourceBundleMessageSource implementation. In particular, it allows for reading files from any Spring resource location (not only from the classpath) and supports hot reloading of bundle property files (while efficiently caching them in between). See the [ReloadableResourceBundleMessageSource](https://docs.spring.io/spring-framework/docs/5.2.7.RELEASE/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html) javadoc for details.

  • ResourceBundleMessageSource의 대안으로 Spring은 ReloadableResourceBundleMessageSource 클래스를 제공한다.
  • 이 변형은 동일한 번들 파일 형식을 지원하지만 표준 JDK 기반 ResourceBundleMessageSource 구현보다 유연하다.
  • 특히 모든 스프링 리소스 위치(클래스 경로뿐만 아니라)에서 파일을 읽을 수 있도록 하고 번들 속성 파일의 핫 reloading(그 사이에 효율적으로 캐싱)를 지원한다.
  • 자세한 내용은 [ReloadableResourceBundleMessageSource](https://docs.spring.io/spring-framework/docs/5.2.7.RELEASE/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html) javadoc을 참조하자.

References

This post is licensed under CC BY 4.0 by the author.

[Spring] 1.15. Additional Capabilities of the ApplicationContext

[Spring] 1.15.2. Standard and Custom Events