본문 바로가기
IT/SpringBoot

MessageSource 기능을 static 메서드로 사용하기

by twofootdog 2022. 3. 18.

스프링부트에서 개발 진행 시 MessageSource를 구현하여 YMAL에 등록한 메시지를 사용한다.

(예를 들면 messageSource.getMessage... 이런 식으로)

그런데 이렇게 되면 메시지를 사용하는 모든 소스에 MessageSource를 의존성 주입을 받아야 하기 때문에 소스코드가 지저분해진다.

그래서 MessageSource를 의존성 주입을 받지 않고, static 메서드로 선언하여 사용하는 방법에 대해 알아볼 것이다.

 

우선 이번 실습을 진행하기 위해서는 MessageSouruce가 구현되어 있어야 가능하다.

 

MessageSource 구현 : 

package com.config;

import net.rakugakibox.util.YamlResourceBundle;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

@Configuration
public class MessageConfig implements WebMvcConfigurer {

    /* 세션에 지역설정. default는 KOREAN = 'ko' */
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.KOREAN);
        return slr;
    }

    /* 지역설정을 변경하는 인터셉터. 요청시 파라미터에 lang 정보를 지정 */
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

    /* 인터셉터를 시스템 레지스트리에 등록 */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

    /* yml 파일을 참조하는 MessageSource 선언(resources/messageCode_ko.yml). MessageSource의 getMessage 메소를 사용해서
    resources/messageCode_ko.yml 접근 */
    @Bean
    public MessageSource messageSource(
            @Value("${spring.messages.basename}") String basename,  // applicaion.yaml의 spring.message.basename
            @Value("${spring.messages.encoding}") String encoding) {
        YamlMessageSource ms = new YamlMessageSource();
        ms.setBasename(basename);
        ms.setDefaultEncoding(encoding);
        ms.setAlwaysUseMessageFormat(true);
        ms.setUseCodeAsDefaultMessage(true);
        ms.setFallbackToSystemLocale(true);
        return ms;
    }

    /* locale 정보에 따라 다른 yaml 파일을 읽도록 처리 */
    private static class YamlMessageSource extends ResourceBundleMessageSource {
        @Override
        protected ResourceBundle doGetBundle(String basename, Locale locale) throws MissingResourceException {
            return ResourceBundle.getBundle(basename, locale, YamlResourceBundle.Control.INSTANCE);
        }
    }
}

 

MessageSource가 구현되었으면, MessageSource를 static으로 선언하는 MessageUtil을 정의해보자.

MessageUtil : 

@Component
public class MessageUtil {

    @Resource
    private MessageSource source;

    static MessageSource messageSource;
  
    @PostConstruct
    public void initialize() {
    messageSource = source;
    }
    
    public static String getMessage(String messageCd) {
    	return messageSource.getMessage(messageCd, null, null);
    }
    
    public static String getMessage(String messageCd, Object[] messageArgs) {
    	return messageSource.getMessage(messageCd, messageArgs, null);
    }
}

 

이렇게 MessageUtil을 구현해 놓으면, 각 클래스에 MessageSource를 선언하지 않아도 MessageUtil.getMessage(...) 과 같은 방식으로 메시지를 가져올 수 있다. 

댓글