Weld на Java SE не использует альтернативу
Я имею projectA
, projectB
, а также projectC
Затмение Maven проектов.
ProjectA
содержит:IMyApi
интерфейс.- "Пустой"
META-INF\beans.xml
файл.
ProjectB
содержит:IMyConfig
интерфейс.MyConfigJndi
реализацияIMyConfig
,MyApiImpl
реализацияIMyApi
, с собственностью@Inject private IMyConfig config;
,- "Пустой"
META-INF\beans.xml
файл.
ProjectC
содержит:MyConfigAlter
реализацияIMyConfig
помечены как@Alternative
,Main
класс (и метод), который инициализирует Weld SE и извлекаетIMyApi
боб.META-INF\beans.xml
гдеMyConfigAlter
указан вalternatives
раздел.
Теперь я бегу Main
класс, а IMyApi
боб успешно получен (как MyApiImpl
пример). Но такой случай был, в его config
собственность, введенная с MyConfigJndi
экземпляр, вместо альтернативной версии (MyConfigAlter
)
Я использую Eclipse Luna + M2Eclipse.
Что я делаю неправильно?
ОБНОВЛЕНИЕ: я узнал, что с помощью @Specializes
вместо @Alternative
решает проблему, но я все еще думаю, что это не правильное решение (в некоторых ситуациях у меня может не быть доступа к реализации по умолчанию).
ОБНОВЛЕНИЕ 2:
Я использую Weld-se, 2.2.10. Наконец:
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.2.10.Final</version>
<scope>runtime</scope>
</dependency>
И инициализация просто
WeldContainer weld =
new Weld().
initialize();
IMyApi myApi =
weld.
instance().
select(
IMyApi.
class).
get();
2 ответа
Выбор альтернативы с помощью alternatives
элемент в beans.xml
дескриптор влияет только на соответствующий архив бина, т.е. ProjectC
в вашем случае, как описано в разделе Объявление выбранных альтернатив для архива бинов. Исходя из этого, это логично, что ProjectB
архив бобов получает MyConfigJndi
реализация внедрена.
Начиная с CDI 1.2, можно глобально выбрать альтернативу для приложения, используя @Priority
аннотация, как описано в разделе Объявление выбранных альтернатив для приложения.
Так что в вашем случае вы могли бы написать:
@Priority(Interceptor.Priority.Application)
@Alternative
class MyConfigAlter {
}
Еще один способ решить эту проблему - использовать -Dorg.jboss.weld.se.archive.isolation=false
- из http://docs.jboss.org/weld/reference/2.2.11.Final/en-US/html/environments.html
Причина, по которой это происходит, заключается в том, что каждый JAR на пути к классам становится своим собственным архивом компонентов. Поскольку спецификация CDI с 1.2 не включает спецификацию SE, нет определения того, как classpath работает в этом режиме. Это не обязательно то, как будет разрабатываться приложение SE, поскольку у вас нет уникальных загрузчиков классов для каждого JAR-файла.