WeldContainer和SeContainer

问题描述 投票:2回答:2

使用之间有什么区别:

WeldContainer se = new Weld().initialize();

SeContainer se = SeContainerInitializer.newInstance().initialize();

我只想使用@Injection@Produce批注,但是我没有发现这两种初始化对象实例的方式之间的区别。

java cdi weld jboss-weld weld2
2个回答
3
投票

上下文和依赖性注入(CDI)是一个规范。这意味着它仅定义API,不提供实现。这就是为什么必须包含诸如[[Weld之类的实现才能真正使用API​​的原因。 WeldContainer类是特定于供应商的,而SeContainer接口是规范的一部分。前者实现后者。

SeContainerInitializer类是API的一部分,它将委托给应用程序附带的实现。因此,如果您使用

Weld

作为实现,那么最终使用SeContainerInitializerSeContainer与“在幕后”使用WeldWeldContainer相同。从纯粹主义者的角度来看,最好仅依赖于规范的接口,而不要直接依赖于实现。这样,您便可以在需要时以及在需要时交换供应商,因为您使用的是所有实现的通用功能。但是,通常情况下,实现提供的功能要比规范要求的功能更多。为了使用该功能,您必须直接依赖于实现。

换句话说,是否使用Weld / WeldContainerSeContainerInitialializer / SeContainer取决于应用程序的(当前和将来)要求。如有疑问,请program to the interface

请注意,API和实现之间的这种分离并非CDI独有。几乎整个

Java EE

-或众所周知的Jakarta EE-API都是这样工作的。一个示例是Java Persistence API(JPA)和HibernateEclipseLink(两个实现)。对于Java SE中的示例,有Java Database Connectivity(JDBC)API和各种实现(即驱动程序)。

1
投票
使用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()方式。
© www.soinside.com 2019 - 2024. All rights reserved.