Weld on Java SE 不使用备选方案
Weld on Java SE does not use alternative
我有 projectA
、projectB
和 projectC
个 Eclipse Maven 项目。
ProjectA
包含:
IMyApi
界面。
- "Empty"
META-INF\beans.xml
文件.
ProjectB
包含:
IMyConfig
界面。
MyConfigJndi
执行 IMyConfig
.
MyApiImpl
IMyApi
的实现,带有 属性 @Inject private IMyConfig config;
.
- "Empty"
META-INF\beans.xml
文件.
ProjectC
包含:
MyConfigAlter
实施 IMyConfig
,标记为 @Alternative
。
- a
Main
class(和方法)初始化 Weld SE 并检索 IMyApi
bean。
- a
META-INF\beans.xml
其中 MyConfigAlter
列在 alternatives
部分。
现在,我 运行 Main
class,IMyApi
bean 被成功检索(作为 MyApiImpl
实例)。但是这样的实例已经在其 config
属性 中注入了 MyConfigJndi
实例,而不是替代版本 (MyConfigAlter
)
我正在使用 Eclipse Luna + M2Eclipse。
我做错了什么?
更新:我发现使用 @Specializes
而不是 @Alternative
可以解决问题,但我仍然认为这不是正确的解决方案(在某些情况下我可能无法访问 "default"实施)。
更新 2:
我正在使用 Weld-se,2.2。10.Final:
<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();
使用 beans.xml
描述符中的 alternatives
元素选择替代项只会影响相应的 bean 存档,即您的情况下的 ProjectC
,如 Declaring selected alternatives for a bean archive 中所述。基于此,ProjectB
bean 存档得到 MyConfigJndi
实现注入是合乎逻辑的。
自 CDI 1.2 起,可以使用 @Priority
注释为应用程序全局 select 替代方案,如 Declaring selected alternatives for an application.
中所述
所以在你的情况下,你可以这样写:
@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#_bean_archive_isolation_2
发生这种情况的原因是类路径上的每个 JAR 都变成了自己的 bean 存档。由于 1.2 的 CDI 规范不包括 SE 规范,因此没有定义类路径如何在此模式下运行。这不一定是 SE 应用程序的设计方式,因为每个 JAR 都没有唯一的类加载器。
我有 projectA
、projectB
和 projectC
个 Eclipse Maven 项目。
ProjectA
包含:IMyApi
界面。- "Empty"
META-INF\beans.xml
文件.
ProjectB
包含:IMyConfig
界面。MyConfigJndi
执行IMyConfig
.MyApiImpl
IMyApi
的实现,带有 属性@Inject private IMyConfig config;
.- "Empty"
META-INF\beans.xml
文件.
ProjectC
包含:MyConfigAlter
实施IMyConfig
,标记为@Alternative
。- a
Main
class(和方法)初始化 Weld SE 并检索IMyApi
bean。 - a
META-INF\beans.xml
其中MyConfigAlter
列在alternatives
部分。
现在,我 运行 Main
class,IMyApi
bean 被成功检索(作为 MyApiImpl
实例)。但是这样的实例已经在其 config
属性 中注入了 MyConfigJndi
实例,而不是替代版本 (MyConfigAlter
)
我正在使用 Eclipse Luna + M2Eclipse。
我做错了什么?
更新:我发现使用 @Specializes
而不是 @Alternative
可以解决问题,但我仍然认为这不是正确的解决方案(在某些情况下我可能无法访问 "default"实施)。
更新 2:
我正在使用 Weld-se,2.2。10.Final:
<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();
使用 beans.xml
描述符中的 alternatives
元素选择替代项只会影响相应的 bean 存档,即您的情况下的 ProjectC
,如 Declaring selected alternatives for a bean archive 中所述。基于此,ProjectB
bean 存档得到 MyConfigJndi
实现注入是合乎逻辑的。
自 CDI 1.2 起,可以使用 @Priority
注释为应用程序全局 select 替代方案,如 Declaring selected alternatives for an application.
所以在你的情况下,你可以这样写:
@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#_bean_archive_isolation_2
发生这种情况的原因是类路径上的每个 JAR 都变成了自己的 bean 存档。由于 1.2 的 CDI 规范不包括 SE 规范,因此没有定义类路径如何在此模式下运行。这不一定是 SE 应用程序的设计方式,因为每个 JAR 都没有唯一的类加载器。