스프링 핵심 기술-06.MessageSource
IoC 컨테이너 7부 : MessageSource
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
...
}
역시 마찬가지로 ApplicationContext가 상속받고 있는 구현체입니다.
MessageSource
- 국제화 (i18n) 기능을 제공하는 인터페이스. (다국어)
- ApplicationContext extends MessageSource
- getMessage(String code, Object[] args, String, default, Locale, loc)
스프링 부트를 사용한다면 별다른 설정 필요없이 messages.properties를 사용할 수 있습니다.
2개의 xml 파일 생성 후.
- messages.properties (xml 파일)
- greeting=Hello, {0}
- messages_ko_kr.properties (xml 파일)
- greeting=안녕, {0}
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
MessageSource messageSource;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(messageSource.getClass());
System.out.println(messageSource.getMessage("greeting", new String[]{"jaeuk"}, Locale.KOREA));
System.out.println(messageSource.getMessage("greeting", new String[]{"jaeuk"}, Locale.getDefault()));
}
}
Locale.KOREA 설정으로 messages_ko_kr.properties가 읽힌 것을 알 수 있고,
제 환경에서는 동일하게 나왔지만, 실습 강사님한테는 영어로 출력된 것을 확인했습니다.
class org.springframework.context.support.ResourceBundleMessageSource
안녕, jaeuk
Hello, jaeuk
동작 원리
- MessageSource 구현체
- org.springframework.context.support.ResourceBundleMessageSource
ResourceBundle 클래스와 MessageFormat클래스 기반으로 만들어 졌으며, 번들에 특정 이름으로 접근가능.
- org.springframework.context.support.ReloadableResourceBundleMessageSource
프로퍼티 설정으로 reloading 하여 application 실행 와중에 번들 변경이 가능하다.
- org.springframework.context.support.StaticMessageSource
MessageSource의 가장 간단한 구현체로 기본적인 국제화를 지원하면 테스트 용도로 만들어짐.
- org.springframework.context.support.ResourceBundleMessageSource
참고
Spring에서 지원하는 MessageSource 3가지 구현체이다.
위의 Class에 대한 bean을 정의하면 ApplicationContext접근을 통하여 대상 메시지를 출력할 수 있다.
이 중 ReloadableResourceBundleMessageSource는 메시지 내용을 캐시하여 가지고 있으며, 인터벌을 지정하여 초단위 간격으로 메시지 파일을 재로딩 하여 어플리케이션의 종료 없이 properties 파일 수정으로 메시지 값 변경이 가능하다.
ResourceBundleMessageSource 빈이 messagese 라는 리소스 번들을 읽게 되어 있다.
스프링 부트에서 자동으로 해 주지만, 우리가 직접 설정을 할 수도 있다.
@SpringBootApplication
@PropertySource("classpath:/app.properties")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
다음은 ReloadableResourceBundleMessageSource를 활용해서,
어플리케이션의 종료 없이 properties 파일 수정으로 메시지 값 변경하는 예제를 구현해보자.
1초마다 찍으면서 리소스를 캐시하는 시간을 3초까지만 캐싱을 하고 다시 읽도록 세팅.
즉, 1초마다 메세지가 찍히고, 수정사항이 3초마다 반영된다. (캐싱은 3초, 값 변경 후 3초면 반영)
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
MessageSource messageSource;
@Override
public void run(ApplicationArguments args) throws Exception {
while(true){
System.out.println(messageSource.getClass());
System.out.println(messageSource.getMessage("greeting", new String[]{"jaeuk"}, Locale.KOREA));
System.out.println(messageSource.getMessage("greeting", new String[]{"jaeuk"}, Locale.getDefault()));
Thread.sleep(1000l);
}
}
}
@SpringBootApplication
@PropertySource("classpath:/app.properties")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3);
return messageSource;
}
}
이렇게 구현된 상태에서 프로퍼티 메세지를 변경하고 빌드만 하면 변경된 메세지가 바로 적용되어서 보여진다.