Компонент Spring ReloadableResourceBundleMessageSource не может найти внешние свойства

#spring #javabeans #cglib #wicket-6 #apache-servicemix

#spring #javabeans #cglib #калитка-6 #apache-servicemix

Вопрос:

Я пытался использовать руководство Mkyong для доступа к файлу внешних свойств, но безуспешно.

Это мое определение компонента в web-osgi-context.xml файл, расположенный в WEB-INF:

 <bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
    <list>
        <value>classpath:bundles/resource</value>
        <value>classpath:bundles/override</value>
        <value>file:c:/test/messages</value>
    </list>
    </property>
    <property name="cacheSeconds" value="10"/>      
</bean>
  

Доступ к компоненту:

 @SpringBean
private ReloadableResourceBundleMessageSource messageSource;
  

Попытка извлечь сообщение следующим образом:

 String name = messageSource.getMessage("customer.name",
        new Object[] { 28,"http://www.mkyong.com" }, Locale.US);

System.out.println("Customer name (English) : "   name);
  

У меня есть файлы messages_en_US.properties в обоих C:/test/messages и C:/test папки. Они содержат следующую строку:

 customer.name=Test, age : {0}, URL : {1}
  

Это все, что у меня есть, я что-то упускаю? Сообщение, которое я получаю, является:

 org.springframework.context.NoSuchMessageException: No message found under code 'customer.name' for locale 'en_US'.
 at org.springframework.context.support.AbstractMessageSource.getMessage(AbstractMessageSource.java:155)
  

Кстати, я также пробовал внутренние свойства, также безуспешно. Я развертываю свой файл .war в своем локальном servicemix(6.1.1), я также использую wicket (6.24.0) и spring (3.2.14). Запуск приложения mkyong (которое не является веб-приложением) локально (без его развертывания в моем локальном servicemix работает).

Комментарии:

1. Похоже, проблема в ServiceMix. Я бы добавил это в теги и надеюсь, что кто-то с опытом ServiceMix поможет.

2. Ну, я думаю, это в основном потому, что это веб-приложение, а не просто строковое приложение. Не тестировал подход mkyongs локально в веб-приложении

Ответ №1:

Ооочень, я несколько обнаружил проблему и получил решение..

Это не сработало:

 <bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename">
        <value>classpath:messages</value>
    </property>
</bean>
  

И в коде:

 @SpringBean
private ReloadableResourceBundleMessageSource messageSource;
  

Запустив getClass() в этом источнике, я получаю

 class WICKET_org.springframework.context.support.ReloadableResourceBundleMessageSource$$EnhancerByCGLIB$$852b0c02
  

Но это работает:

 @Bean
public MessageSource messageSource() {
     ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
     messageSource.setBasename("classpath:messages");
     return messageSource;
}
  

Запустив getClass() в этом источнике, я получаю

 class org.springframework.context.support.ReloadableResourceBundleMessageSource
  

Возможно ли, что усилитель Cglib здесь что-то путает? Как я могу заставить первый вариант работать, зная это?

Комментарии:

1. Wicket использует CGlib для создания прокси-сервера вокруг компонента Spring, но любые вызовы метода на этом прокси-сервере делегируются реальному компоненту. Таким образом, реальный компонент выполняет логику для поиска сообщения, а не прокси. Кроме того, местоположение является корнем пути к классу, поэтому на самом деле не имеет значения, какой класс используется.

2. Как я предположил в комментариях к вопросу: проблема в ServiceMix. Он основан на OSGi, и пути к классам и загрузчики классов ведут себя там иначе, чем на обычном веб-сервере сервлетов.

3. Если нет разницы между тем, какой из них используется, то почему второй работает для меня, а первый — нет?