복붙노트

[SPRING] Spring Framework의 주석을 통해 resourceBundle에서 지역화 된 메시지 가져 오기

SPRING

Spring Framework의 주석을 통해 resourceBundle에서 지역화 된 메시지 가져 오기

이것을 할 수 있습니까? 현재 다음과 같이 처리됩니다.

<bean id="resource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>content.Language</value> 
        </list>
    </property>
</bean>

@Autowired
protected MessageSource resource;

protected String getMessage(String code, Object[] object, Locale locale) {
    return resource.getMessage(code, object, locale);
}

@Value 주석을 통해 속성을 가져 오는 것과 같은 방법일까요?

<util:properties id="generals" location="classpath:portlet.properties" />

    @Value("#{generals['supported.lang.codes']}")
    public String langCodes;

메서드를 호출하는 것은 일반적으로 괜찮지 만, 예를 들어 단위 테스트를하는 경우에는 고통 스럽습니다 ... ... 어떤 경우에는 객체가 초기화되지 않은 Webdriver의 PageObject 패턴이 유용합니다

해결법

  1. ==============================

    1.나는 두 가지 개념을 혼합했다고 생각합니다.

    나는 두 가지 개념을 혼합했다고 생각합니다.

    특성 파일은 특성을 포함합니다 (로 I 일 독립). Spring에서는 util : properties를 통해로드 할 수 있으며 @Value 주석에 사용할 수 있습니다.

    그러나 메시지 자원 번들 (등록 정보 파일처럼 보이는 파일의 기반)은 언어 의존적입니다. Spring에서는 org.springframework.context.support.ResourceBundleMessageSource를 통해로드 할 수있다. 그러나 @Value를 통해 String에 삽입하지 마십시오. @Value 주입은 bean마다 한 번 수행되고, @Value는 한 번 (시작 시간에 가장 많이) 평가되며, 계산 된 값이 주입 될 것이므로 주입 할 수 없습니다. 그러나 메시지 리소스 번들을 사용할 때 일반적으로 필요한 것은 아닙니다. 왜냐하면 사용자의 언어에 따라 변수가 사용될 때마다 값을 평가해야하기 때문입니다.

    그러나 당신은 당신 자신의 그것을 쉽게 만들 수 있습니다!

    필요한 클래스는 다음과 같습니다.

    import java.util.Locale;    
    import javax.annotation.Resource;    
    import org.springframework.beans.factory.annotation.Configurable;
    import org.springframework.context.MessageSource;
    import org.springframework.context.i18n.LocaleContextHolder;
    
    @Configurable
    public class MSG {
    
        private String key;
    
        @Resource(name = "messageSource")
        private MessageSource messageSource;
    
        public MSG(String key) {
            super();
            this.key = key;        
        }
    
        public String value() {
            Locale locale = LocaleContextHolder.getLocale();                        
            return messageSource.getMessage(key, new Object[0], locale);
        }
    
        @Override
        public String toString() {
            return value();
        }
    }
    

    그런 다음이 방법으로 사용할 수 있습니다.

    @Service
    public class Demo {
    
        @Value("demo.output.hallo")
        private MSG hallo;
    
        @Value("demo.output.world")
        private MSG world;
    
        public void demo(){
            System.out.println("demo: " + hello + " " + world);
        }    
    }
    

    실행을 위해서는 AspectJ @Configurable 지원을 켜려면 를 활성화해야하고, Ressouce Bundle Message Source를 동일한 애플리케이션 컨텍스트에 인스턴스화해야하는 경우 (예 : web 응용 프로그램에서는 ReloadableResourceBundleMessageSource 정의를 웹 응용 프로그램 컨텍스트의 대부분의 경우에 넣지 만 MSG 객체가 "일반"응용 프로그램 컨텍스트에 있기 때문에이 경우에는 작동하지 않습니다.

  2. ==============================

    2.중요한 것은 단위 테스트에만 유용하다는 것입니다. 실제 응용 프로그램에서 Locale은 주석에 하드 코드 될 수없는 런타임 정보입니다. 로켈은 런타임의 사용자 로캘에 따라 결정됩니다.

    중요한 것은 단위 테스트에만 유용하다는 것입니다. 실제 응용 프로그램에서 Locale은 주석에 하드 코드 될 수없는 런타임 정보입니다. 로켈은 런타임의 사용자 로캘에 따라 결정됩니다.

    Btw를 사용하면 다음과 같이 직접 구현할 수 있습니다.

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface Localize {
    
        String value();
    
    }
    

    public class CustomAnnotationBeanPostProcessor implements BeanPostProcessor {
    
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            Class clazz = bean.getClass();
            do {
                for (Field field : clazz.getDeclaredFields()) {
                    if (field.isAnnotationPresent(Localize.class)) {
                        // get message from ResourceBundle and populate the field with it
                    }
                }
                clazz = clazz.getSuperclass();
            } while (clazz != null);
            return bean;
        }
    
  3. from https://stackoverflow.com/questions/6246381/getting-localized-message-from-resourcebundle-via-annotations-in-spring-framewor by cc-by-sa and MIT license