Spring - I18n - 在静态类上访问MessageSource?

时间:2015-10-13 13:40:00

标签: java spring internationalization vaadin

我按照了这样一些教程:

http://www.concretepage.com/spring-4/spring-4-mvc-internationalization-i18n-and-localization-l10n-annotation-example

让i18n在我的spring(boot)项目中工作。 它到目前为止工作,但我不喜欢它总是将MessageSource bean自动装配到我当前的课堂上,只是为了翻译一些String

我的想法是一个简单的包装类,带有静态调用,如

I18n.translate("some.identifier") 

I18n.translate("some.identifier",param,param,param...).

但是我无法将MessageSource注入一个不由Spring处理的类中,是吗?

知道如何解决这个问题吗?

6 个答案:

答案 0 :(得分:2)

你可以(不确定你是否应该)这样做:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class StaticContextAccessor {

    private static StaticContextAccessor instance;

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void registerInstance() {
        instance = this;
    }

    public static <T> T getBean(Class<T> clazz) {
        return instance.applicationContext.getBean(clazz);
    }

}

然后像这样使用它:

SomeOtherwiseAutowiredClass someObject = StaticContextAccessor.getBean(SomeOtherwiseAutowiredClass.class);

答案 1 :(得分:0)

您有两种可能性:

  1. 静态属性/字段的非静态setter;
  2. 使用org.springframework.beans.factory.config.MethodInvokingFactoryBean调用静态setter。
  3. 您可以找到的示例请点击链接 How to make spring inject value into a static field

    P.S。 autowire MessageSource进入bean的问题是什么?

答案 2 :(得分:0)

创建静态消息源包装器,例如https://github.com/chelu/jdal/blob/master/core/src/main/java/org/jdal/beans/StaticMessageSource.java

并在bean配置文件中声明它:

<!-- Message Source -->
<bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames" value="i18n/jdal,i18n/i18n" />
</bean>

<bean id="staticMessageSource" class="org.jdal.beans.StaticMessageSource">
        <constructor-arg ref="messageSource" />
</bean>

请注意,如果您需要在其他bean之前实例化包装器,则可以使用depend-on

答案 3 :(得分:0)

我有同样的想法,也就是与Vaadin一起开发的,对我有用的解决方案是使用StaticContextInitializer Bean。因此,请执行以下操作:

首先将您的Message类字段设为静态,并提供getter和setter方法:

private static MessageSource messageSource;

private TextSource() {
}

public static String getText(String key, Locale locale) {
    return messageSource.getMessage(key,null, ensureLocale(locale));
}



public static String getText(String key, Locale locale, Object[] parameter) {
    return messageSource.getMessage(key, parameter, ensureLocale(locale));
}

private static Locale ensureLocale(Locale locale) {
    if (locale == null)
        locale = Locale.getDefault();
    return locale;
}

将静态设置方法添加到类中:

public static void setMessageSource(MessageSource messageSource) {
    TextSource.messageSource = messageSource;
}

使用@PostConstruct注释编写您的StaticInitializer Bean,并使用@Autowired注释注入MessageSource。

@Component
public class FrontendStaticContextInitializer {

@Autowired
private MessageSource messageSource;

@PostConstruct
public void initialize() {
    TextSource.setMessageSource(messageSource);
}
}

之后,您将可以在视图中调用该类:TextSource.getText("login.textfield.placeholder.benutzername", getLocale())

答案 4 :(得分:0)

只需实现MessageSourceAware并将其设置为静态变量即可。 但是,只有在 spring.main.lazyInitialization false 的情况下,它才起作用。

@Component
public final class MessageUtils implements MessageSourceAware {

    private static MessageSource messageSource;

    @Override
    public void setMessageSource(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }

    public static String getMessage(String key, String... params) {
        return messageSource.getMessage(key, params, new Locale("PT", "br"));
    }

}

如果 spring.main.lazyInitialization true ,则需要强制注入:

public class App {

    @Autowired
    private MessageUtils messageUtils;

    public static void main(String[] args) {
        SpringApplication.run(App .class, args);
    }

}

Spring将自动注入,请参阅类:ApplicationContextAwareProcessor.invokeAwareInterfaces(Object bean)

enter image description here

答案 5 :(得分:0)

这里是一个示例 Utils,没有 DI 概念,没有 Bean 配置:

import java.util.Locale;

import org.apache.commons.lang3.Validate;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

public class I18n {
    private static MessageSource MESSAGE_SOURCE;
    static {
        I18nUtils.MESSAGE_SOURCE = messageSource();
    }

    public static String translate(Locale locale, String key, Object... args) {
        Validate.notNull(locale, "locale require not null");
        Validate.notEmpty(key, "key require not empty");
        return MESSAGE_SOURCE.getMessage(key, args, locale);
    }

    private static MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.addBasenames("classpath:Messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}