Java 在Spring框架中通过注释从resourceBundle获取本地化消息

Java 在Spring框架中通过注释从resourceBundle获取本地化消息,java,spring,localization,annotations,resourcebundle,Java,Spring,Localization,Annotations,Resourcebundle,有可能这样做吗?目前是这样做的: <bean id="resource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>content.Language</value> </list&

有可能这样做吗?目前是这样做的:

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

内容、语言
@自动连线
受保护的消息源资源;
受保护的字符串getMessage(字符串代码、对象[]对象、区域设置){
返回resource.getMessage(代码、对象、区域设置);
}
有没有办法让它像通过@Value注释获取属性一样

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

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

@值(“#{generals['supported.lang.codes']}”)
公共字符串语言码;

因为必须调用该方法通常是好的,但例如在单元测试时,这是痛苦的。。。在某些情况下,webdriver的PageObject模式中的对象没有初始化,这将非常有用

关键是,这只对单元测试非常有用。在实际应用程序中,Locale是一种运行时信息,不能在注释中硬编码。语言环境是根据用户在运行时的语言环境确定的

顺便说一句,您可以自己轻松实现这一点,例如:

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

    String value();

}


我相信你混淆了两个概念:

  • 属性文件
  • 消息资源包

属性文件包含属性(与区域设置无关)。在Spring中,它们可以通过
util:properties
加载,并可用于
@Value
注释

但是消息资源包(基于看起来像属性文件的文件)依赖于语言。在Spring中,您可以通过
org.springframework.context.support.ResourceBundleMessageSource
加载它们。但不能通过
@Value
插入字符串。您不能注入它们,因为
@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捆绑包消息源(例如,在web应用程序中,在大多数情况下,您将
ReloadableResourceBundleMessageSource
定义放在web应用程序上下文中,但在这种情况下,这不起作用,因为MSG对象处于“正常”状态。)应用程序上下文。

我还想知道为什么这个功能不存在,在3.1和3.2中可能没有实现。supported.lang.code是属性文件的键值对,还是应该是所有支持语言的编程计算值?它只是属性文件的键值。实际上非常方便这不是获取属性的方式。我希望Spring会提供类似于本地化的东西……比如@Localize(“#{langCode['some.error.message]}”)Ralph,我没有混淆任何东西,我两个都用了3年。我只是说如果Spring有它,单元测试会很方便。我按照Edgar说的做了,我使用BeanPostProcessor从ResourceBundle填充带注释的字段。我认为这是一个比使用@Value annotation更好的解决方案。但是非常感谢您的展示这个@Value annotation的用例,我不知道我能做到。你我明白了,你被“via@Value annotation”搞糊涂了。我不是说使用@Value annotation本身,我是说“via annotations”
@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);
    }    
}