使用有什么区别:
WeldContainer se = new Weld().initialize();
或者
SeContainer se = SeContainerInitializer.newInstance().initialize();
我只是想使用@Injection
和@Produce
注解,但是我没有发现这两种初始化对象实例的方式的区别。
使用有什么区别:
WeldContainer se = new Weld().initialize();
或者
SeContainer se = SeContainerInitializer.newInstance().initialize();
我只是想使用@Injection
和@Produce
注解,但是我没有发现这两种初始化对象实例的方式的区别。
上下文和依赖注入(CDI) 是一种规范。这意味着它只定义了一个 API,不提供实现。这就是为什么您必须包含诸如Weld之类的实现才能实际使用 API 的原因。该类WeldContainer
是特定于供应商的,而SeContainer
接口是规范的一部分。前者实现后者。
作为 API 一部分的SeContainerInitializer
类将委托给应用程序中包含的实现。因此,如果您使用Weld作为实现,那么最终使用SeContainerInitializer
andSeContainer
与使用Weld
和WeldContainer
“幕后”相同。
从纯粹主义者的角度来看,最好只依赖规范的接口,而永远不要直接依赖于实现。这样,您可以在需要时交换供应商,因为您使用的是所有实现通用的功能。但是,通常实现提供的功能比规范要求的要多。为了使用该功能,您必须直接依赖于实现。
换句话说,是否使用Weld
/WeldContainer
或SeContainerInitialializer
/SeContainer
取决于您的应用程序的(当前和未来)需求。如有疑问,请对界面进行编程。
请注意,API 和实现之间的这种分离并不是 CDI 独有的。几乎整个Java EE(或者现在已知的Jakarta EE ) API 都以这种方式工作。Java Persistence API (JPA) 和Hibernate或EclipseLink(两种实现)就是一个例子。对于Java SE中的示例,有Java 数据库连接(JDBC) API 和各种实现(即驱动程序)。
使用SeContainerInitializer
它将加载一个实例ServiceLoader.load(...)
并对其进行初始化。
public static SeContainerInitializer newInstance() {
return findSeContainerInitializer();
}
private static SeContainerInitializer findSeContainerInitializer() {
SeContainerInitializer result;
Iterator<SeContainerInitializer> iterator = ServiceLoader.load(SeContainerInitializer.class, SeContainerInitializer.class.getClassLoader()).iterator();
if (!iterator.hasNext()) {
throw new IllegalStateException("No valid CDI implementation found");
}
try {
result = iterator.next();
} catch (ServiceConfigurationError e) {
throw new IllegalStateException("Error while instantiating SeContainerInitializer", e);
}
if (iterator.hasNext())
throw new IllegalStateException("Two or more CDI implementations found, only one is supported");
return result;
}
Weld 是一种实现,SeContainerInitializer
因此如果它存在于类路径SeContainerInitializer.newInstance()
方法中,它将创建一个新Weld
实例并initialize()
在该对象上调用方法。
一些提示,这是一个不错的选择
SeContainerInitializer.newInstance()
是一种工厂方法。如果您想创建一个独立于供应商的应用程序,那就太好了。但是 Weld 是 CDI 规范的参考实现。老实说,我认为没有必要选择其他实现。
new Weld().initialize()
将创建一个WeldContainer
(这是 的实现SeContainer
)。使用这种方法,您将获得供应商锁定,但您可以使用许多有用的额外功能(例如,以编程方式添加替代方案或拦截器)。
我的意见是:在这种情况下,供应商锁定无关紧要。
结论
如果您打算更改 CDI 实现,除了 Weld 以外的任何其他内容,请使用独立SeContainerInitializer.newInstance()
的,否则只需创建一个Weld
实例。如果我是你,我会使用new Weld()
方式。