Как внедрить несериализуемый класс (например, java.util.ResourceBundle) с помощью Weld - PullRequest
20 голосов
/ 08 июня 2010

Я хочу создать источник, который позволит внедрить java.util.ResourceBundle в любой класс, чтобы легко получить локализованные строки.Мой ResourceBundle-Producer выглядит следующим образом:

public class ResourceBundleProducer {
  @Inject       
  public Locale locale;

  @Inject       
  public FacesContext facesContext;

  @Produces
  public ResourceBundle getResourceBundle() {
    return ResourceBundle.getBundle("/messages", locale )
  }
}

Работает Injection of Locale и FacesContext (взял соответствующих производителей из Seam 3 Alpha Source).Но, к сожалению, ResourceBundle не Serializable и, следовательно, не может быть создан таким образом.При попытке получить доступ к JSF-странице, вызывающей компонент, использующий мой ResourceBundle, я получаю следующую ошибку:

Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()\\nInjection Point\: field web.PersonHome.bundle

Есть ли способы заставить мой ResourceBundleResolverРабота?Или есть какие-то другие механизмы, чтобы получить подобную функциональность?Заранее спасибо!

РЕДАКТИРОВАТЬ:

Хорошо, я потратил некоторые из моих едва заработанных очков;) Также приму хороший обходной путь для этой проблемы!

У меня есть другой пример, когда создание производителя не работает: FlashProducer.FacesContext-Flash также не может быть создан, потому что Flash не сериализуем.

Ответы [ 2 ]

25 голосов
/ 17 июля 2010

Ну, во-первых, ResourceBundle не сериализуем . Смотрите здесь . И сообщение ясно

не может создать не сериализуемых экземпляров для инъекции в непереходных полей пассивирующих бобов

пассивирующие бобы ??? Я думаю, что web.PersonHome является либо сессионным компонентом с состоянием, либо компонентом @ConversationScoped. Я прав ??? Если это так, вы должны пометить свойство пакета как переходное

private transient @Inject ResourceBundle bundle;
3 голосов
/ 05 февраля 2014

Согласно ветке комментариев в принятом ответе Артура. Я следовал этому блогу , а также этому блогу , чтобы провести эксперимент по пассивации / активации. Эксперимент подтвердил комментарий MrD, что переходное свойство при активации будет иметь значение NULL. Таким образом, чтобы иметь дело с несериализуемыми свойствами-членами bean-компонента, способного к пассивации (а именно, сессионного контекста, сеансового контекста и сессионного компонента с состоянием), я предлагаю следующее решение:

private ResourceBundle bundle;

@PostConstruct
@PostActivate
public void getResourceBundle() {
    bundle = ResourceBundle.getBundle("/messages", locale );
}

Это решение обеспечивает повторную инициализацию несериализуемых членов свойства при каждом переходе в состояние READY.

Последний вопрос по адресу

Последней проблемой, которую необходимо решить, является внедрение регистратора SLF4j, который не был сериализуемым до slf4j 1.5.3, и я цитирую :

Начиная с SLF4J версии 1.5.3, экземпляры регистратора выдерживают сериализацию. Таким образом, сериализация класса хоста больше не требует специальных действие, даже если регистраторы объявлены как переменные экземпляра.

Таким образом, если ваша зависимость slf4j составляет 1.5.3 или более поздней, вы можете безопасно внедрить регистратор SLF4j следующим образом:

@Produces
@LogbackLogger
public Logger produceLogger(InjectionPoint injectionPoint){
    return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}

Предположим, вы указали квалификатор:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface LogbackLogger {
}

Затем в bean-компоненте, способном к пассивации, ввести следующее:

@Inject
@LogbackLogger
private Logger logger;
...