[스프링 IoC 컨테이너와 빈]_08 MessageSource
MessageSource
국제화 (i18n) 기능을 제공하는 인터페이스.
ApplicationContext extends MessageSource
● getMessage(String code, Object[] args, String, default, Locale, loc)
● …
스프링 부트를 사용한다면 별다른 설정 필요없이 messages.properties 사용할 수 있음
● messages.properties
● messages_ko_kr.properties
● …
릴로딩 기능이 있는 메시지 소스 사용하기
@Bean
public MessageSource messageSource() {
var messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3);
return messageSource;
}
MessageSource
-
메시지를 다국화하는 방법
-
ApplicationContext가 MessageSource를 상속받았기 때문에 이 기능을 할 수 있다.
MessageSource 사용하기
※ [실습]
1. MessageSource에 해당하는 값을 별도의 파일로 생성
messages.properties
, messages_ko_KR.properties
, messages_en.properties
- messages.properties
greeting=Hello {0}
- messages_ko_KR.properties
greeting=안녕, {0}
- messages_en.properties
greeting=Hello, {0}
별도의 설정을 하지 않고, 위와같이 파일을 만들면 스프링부트 애플리케이션은 messages
로 시작하는 MessageSource들을 전부 읽어주기 때문에 바로 사용할 수 있다.
자동으로 Bundle로 인식한다.
2. ApplicationRunner에서 MessageSource 사용
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
MessageSource messageSource;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.getDefault()));
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.KOREA));
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.ENGLISH));
}
}
(왜 default로 한글이 나오는지는 모르겠다.?)
원래는 관련빈을 빈으로 등록해줘야하는데, 스프링부트를 사용하면 미리 ResourceBundleMessageSource
가 빈으로 등록되어있다. 이 빈이 messages
라는 Resource Bundle을 읽게된다.
System.out.println(messageSource.getClass()); //-> class org.springframework.context.support.ResourceBundleMessageSource
릴로딩 기능이 있는 메시지 소스 사용하기
스프링부트가 기본적으로 설정해주는 기능을 우리가 커스텀해서 사용할 수 있다.
※ [실습]
MessageSource를 직접 빈으로 등록
-
빈 id는 항상
messageSource
가 되어야한다. -
setBasename
- 메세지 프로퍼티파일의 위치와 이름을 지정
- basename은 classpath 기준으로 줘야한다.
messages
를 읽는다.
-
setDefaultEncoding
- 기본 인코딩을 지정
- setDefaultEncoding(“UTF-8”) : 한글 인코딩
-
setCacheSeconds
- 프로퍼티 파일의 변경을 감지할 시간 간격을 지정
-
setUseCodeAsDefaultMessage
- 없는 메세지일 경우 예외를 발생시키는 대신 코드를 기본 메세지로 한다.
애플리케이션 실행 중에 프로퍼티 값을 변경 후, 재 빌드!!하면 값이 바로 적용된다.
@SpringBootApplication
public class Demospring51Application {
public static void main(String[] args) {
SpringApplication.run(Demospring51Application.class, args);
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3); //<-- 3초 마다 변경 감지
return messageSource;
}
}
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
MessageSource messageSource;
@Override
public void run(ApplicationArguments args) throws Exception {
while(true) {
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.getDefault()));
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.KOREA));
System.out.println(messageSource.getMessage("greeting", new String[]{"Solar"}, Locale.ENGLISH));
Thread.sleep(10001); //1초마다 콘솔에 찍으면서 값이 변경되는지 확인
}
}
}
참고
MessageSource messageSource;
대신 ApplicationContext messageSource
타입으로 받아서 사용할 수 있지만, 내가 사용하려는 인터페이스로 정확히 명시해주는 것이 어떤 의도로 사용하려는지 목적이 분명하므로 권장된다.