6

我无法使“数据库驱动的资源包”工作。在下面TextDAO的示例中,在应用程序启动期间正确注入,但是当messageSource被访问时,Messages会创建一个新对象——这就是重点。如何使这项工作?

<!-- message source -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="someapp.bundle.Messages" />
</bean>

消息.java

@Component
public class Messages extends ListResourceBundle {

    @Autowired
    private TextDAO textDAO;

    public Messages() {
        log.debug("CONSTRUCTOR");
    }

    @Override
    protected Object[][] getContents() {
        // loading messages from DB
        List<Text> texts = textDAO.findAll();  // textDAO is null
        ...
    }
}

重新打开

正如我所Bozho建议的那样,我做了如下的资源包,但是动态重新加载它有问题。我想 ReloadableResourceBundleMessageSource 是用于属性文件的,但也许也可以这样做。

public class DatabaseDrivenMessageSource extends ReloadableResourceBundleMessageSource {

    private Logger log = LoggerFactory.getLogger(getClass());

    private final Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>();

    private TextDAO textDAO;

    @Autowired
    public DatabaseDrivenMessageSource(TextDAO textDAO) {
        this.textDAO = textDAO;
        reload();
    }

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        String msg = getText(code, locale);
        MessageFormat result = createMessageFormat(msg, locale);
        return result;
    }

    @Override
    protected String resolveCodeWithoutArguments(String code, Locale locale) {
        return getText(code, locale);
    }

    private String getText(String code, Locale locale) {
        Map<String, String> localized = properties.get(code);
        String textForCurrentLanguage = null;
        if (localized != null) {
            textForCurrentLanguage = localized.get(locale.getLanguage());
            if (textForCurrentLanguage == null) {
                textForCurrentLanguage = localized.get(Locale.ENGLISH.getLanguage());
            }
        }
        return textForCurrentLanguage != null ? textForCurrentLanguage : code;
    }

    public void reload() {
        properties.clear();
        properties.putAll(loadTexts());
    }

    protected Map<String, Map<String, String>> loadTexts() {
        log.debug("loadTexts");
        Map<String, Map<String, String>> m = new HashMap<String, Map<String, String>>();
        List<Text> texts = textDAO.findAll();
        for(Text text: texts) {
            Map<String, String> v = new HashMap<String, String>();
            v.put("en", text.getEn());
            v.put("de", text.getDe());
            m.put(text.getKey(), v);
        }
        return m;
    }
}
4

3 回答 3

3

basename是一个字符串,所以它不是一个spring bean,因此没有注入。

您可以尝试做的是子类化ReloadableResourceBundleMessageSource并覆盖那里的一些方法(例如 - getMessage(..))。DAO 应该被注入到子类中。

于 2011-03-31T14:28:26.580 回答
2

ReloadableResourceBundleMessageSource创建由basename属性命名的类的实例。这个实例不会有任何由 Spring 注入的依赖项。这就是为什么您的对象中的textDAO字段为空的原因。Messages

此 Spring 问题具有示例 JDBC 支持的 MessageSource 的源代码,作为附件,您可以使用它来代替ReloadableResourceBundleMessageSource.

于 2011-03-31T15:07:29.167 回答
0

有点旧,但仍然相关......我正在使用带有 JDBC 后端的 Spring Cloud Config 服务器作为 i18n 的资源包。零代码。效果很棒!

于 2019-04-29T12:36:58.143 回答