스프링 프레임워크 MessageSource 설정
26 Feb 2022백기선님의 ‘스프링 프레임워크 핵심 기술’ 강의 정리
MessageSource
- 국제화(i18n) 기능을 제공하는 인터페이스
public interface ApplicationContext extends MessageSource ... {
String getMessage(String code, @Nullable Object[] args, Locale locale)
}
-
ApplicationContext
가MessageSource
를 상속받으므로 ApplicationContext를 주입받으면, MessageSource 기능도 사용 가능 -
스프링 부트를 사용하면 설정없이 messages.properties 사용 가능
-
messages_ko_KR.properties
-
message_en_US.properties
-
메세지 프로퍼티를 추가해서 앱 러너에서 확인해보도록 하자.
# messages_ko_KR.properties
greeting=안녕 {0}
# messages.properties
greeting=Hello {0}
앱 러너에서도 메세지를 가져올 수 있도록 코드를 추가한다.
@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[]{"there"}, Locale.getDefault()));
System.out.println(messageSource.getMessage("greeting", new String[]{"there"}, Locale.KOREA));
}
}
앱을 실행하자 ?? there
이라는 문구만 출력됐다. 인코딩 문제를 먼저 해결해야만 했다. 인텔리제이에서 Preferences
- Editor
- Code Style
- File Encodings
에서 UTF-8 설정을 해줘야만 한다. 그냥 Preferences에서 encoding만 검색해도 빠르게 찾을 수 있다. 아래의 표시된 곳의 인코딩 설정을 UTF-8로 바꿔주도록 한다.
인코딩 설정을 마치고 다시 앱을 실행하자 안녕 there이 두 번 출력되었다. Locale 기본값이 한국어로 되어있던 듯 했다. 영어 버전을 출력하기 위해 프로퍼티를 여러번 수정해보았다. 기본 locale이 한국어이기 때문에 기존의 messages_ko_KR.properties
을 messages.properties
로 바꾸고 영어 버전을 추가하기 위해 message_en_US.properties
로 변경했다. 앱 러너에서는 Locale.ENGLISH
로 설정하도록 했다.
# messages.properties
greeting=안녕 {0}
# messages_en_US.properties
greeting=Hello {0}
@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[]{"there"}, Locale.getDefault()));
System.out.println(messageSource.getMessage("greeting", new String[]{"there"}, Locale.ENGLISH));
}
}
이렇게 설정하고 앱을 실행하자 Locale.getDefault()로 설정한 곳은 한국어로, Locale.ENGLISH로 설정한 곳은 영어 설정을 읽어서 의도대로 잘 출력되었다.
MessageSource를 빈으로 등록해서 원하는대로 설정을 할수도 있다. UTF-8 설정을 해주지 않으면 인코딩이 깨지므로 여기에도 인코딩 설정을 해주도록 한다.
@SpringBootApplication
public class SpringCoreApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCoreApplication.class, args);
}
@Bean
public MessageSource messageSource() {
var messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
그 다음, 앱 러너로 가서 기존의 문구를 1초 간격으로 출력하도록 코드를 조금 수정해본다.
@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[]{"there"}, Locale.getDefault()));
System.out.println(messageSource.getMessage("greeting", new String[]{"there"}, Locale.ENGLISH));
Thread.sleep(1000L);
}
}
}
리로드가 가능한 메세지소스를 빈으로 등록했기 때문에 중간에 메세지 프로퍼티를 수정해도 바로 반영이 된다. 메세지 소스의 캐시 시간 설정만 추가해주도록 한다.
@SpringBootApplication
public class SpringCoreApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCoreApplication.class, args);
}
@Bean
public MessageSource messageSource() {
var messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3);
return messageSource;
}
}
이렇게 모두 수정한 후에 앱을 실행하면 계속 문구가 출력될 것이다. 중간에 메세지 프로퍼티의 문구를 바꿔준 후에 Build
- Build Project
를 클릭하면 앱을 껐다가 다시 실행하지 않아도 바꾼 메세지가 적용된다. 빌드된 디렉토리의 클래스패스를 읽어들여서 동작하기 때문에 꼭 프로젝트 빌드를 해줘야 한다.