복붙노트

[SPRING] Spring의 데이터베이스 중심 리소스 번들

SPRING

Spring의 데이터베이스 중심 리소스 번들

"데이터베이스 기반 리소스 번들"작업을 수행하는 데 문제가 있습니다. 아래 예제에서 TextDAO는 응용 프로그램 시작 중에 적절하게 주입되지만 messageSource에 액세스하면 새 Messages 객체가 만들어집니다. 이 작품을 만드는 방법?

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

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

해결법

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

    1.basename은 문자열이므로 스프링 빈이 아니므로 거기에 주입 할 필요가 없습니다.

    basename은 문자열이므로 스프링 빈이 아니므로 거기에 주입 할 필요가 없습니다.

    당신이 할 수있는 일은 ReloadableResourceBundleMessageSource를 서브 클래스 화하고 거기서 몇몇 메소드를 오버라이드하는 것입니다 (예를 들어 - getMessage (..)). DAO는 서브 클래스에 주입되어야한다.

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

    2.ReloadableResourceBundleMessageSource는 basename 속성에 의해 명명 된 클래스의 인스턴스를 만듭니다. 이 인스턴스는 Spring에 의해 삽입 된 의존성을 가지지 않을 것이다. 그래서 Messages 객체의 textDAO 필드가 null입니다.

    ReloadableResourceBundleMessageSource는 basename 속성에 의해 명명 된 클래스의 인스턴스를 만듭니다. 이 인스턴스는 Spring에 의해 삽입 된 의존성을 가지지 않을 것이다. 그래서 Messages 객체의 textDAO 필드가 null입니다.

    이 Spring 문제에는 예제로 JDBC 지원 MessageSource에 대한 소스 코드가 첨부 파일로 있는데, ReloadableResourceBundleMessageSource 대신 사용할 수 있습니다.

  3. from https://stackoverflow.com/questions/5498998/database-driven-resource-bundle-in-spring by cc-by-sa and MIT license