Search code examples
javaspringlocalizationannotationsresourcebundle

Getting localized message from resourceBundle via annotations in Spring Framework


Is it possible to do this ? Currently it is done like this :

<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);
}

Is there a way for it to be like getting properties via @Value annotation ?

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

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

Because having to call the method is usually fine, but for instance when unit testing, this is pain in ... ... Well in some cases, webdriver's PageObject pattern where objects don't have no initialization, this would be really helpful


Solution

  • The point is that this is really useful only for Unit Testing. In real application, Locale is a runtime information that cannot be hardcoded in the annotation. Locale is decided based on Users locales in Runtime.

    Btw you can easily implement this by yourself, something like :

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

    And

    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;
        }