Jakarta ee 如何以编程方式添加可移植CDI扩展?

Jakarta ee 如何以编程方式添加可移植CDI扩展?,jakarta-ee,cdi,weld,Jakarta Ee,Cdi,Weld,创建可移植CDI扩展(like)的示例都使用javax.enterprise.inject.spi.Extension扩展点来允许ServiceLoader加载扩展 是否有一个Weld/CDIAPI/SPI以编程方式动态注册扩展 我意识到生命周期可能是一个问题,因为您启动应用程序时没有提供此扩展,在某些方面可能“太晚了”,但还是想问一下。具体地说,我想知道一个EE环境。据我所知,没有官方的API来支持它 我知道根据您的用例,您可能需要尝试两种方法/选项 添加动态创建spi服务文件的自定义类加载

创建可移植CDI扩展(like)的示例都使用javax.enterprise.inject.spi.Extension扩展点来允许ServiceLoader加载扩展

是否有一个Weld/CDIAPI/SPI以编程方式动态注册扩展


我意识到生命周期可能是一个问题,因为您启动应用程序时没有提供此扩展,在某些方面可能“太晚了”,但还是想问一下。具体地说,我想知道一个EE环境。

据我所知,没有官方的API来支持它

我知道根据您的用例,您可能需要尝试两种方法/选项

  • 添加动态创建spi服务文件的自定义类加载器

  • 你可以看看这个问题的根源。上次我查看时,它使用反射和特定于实现的类来访问Weld的内部,从而影响初始化。除了测试之外,我不推荐这种方法

为什么要动态加载扩展


一个简单的解决方案可能是始终加载扩展并让它决定实际执行某些操作。

据我所知,没有官方API支持这一点

我知道根据您的用例,您可能需要尝试两种方法/选项

  • 添加动态创建spi服务文件的自定义类加载器

  • 你可以看看这个问题的根源。上次我查看时,它使用反射和特定于实现的类来访问Weld的内部,从而影响初始化。除了测试之外,我不推荐这种方法

为什么要动态加载扩展


一个简单的解决方案可能是始终加载扩展并让它决定实际执行某项操作。

简单回答-CDI故意不提供API来动态添加扩展。事实上,你不应该试图做到这一点

一点原因:

CDI本质上是静态的——它在引导过程中需要某些信息,扩展就是其中之一。一旦引导完成,扩展大部分就变得无用了(当然,您仍然可以将它们作为bean使用,并且在那里有一些逻辑,但是它只是一个bean)。原因是扩展钩住了引导循环,并且可以影响每个阶段(
ProcessAnnotatedType
ProcessBeanAttributes
,…)

现在,如果您稍后以某种方式加载了这样一个扩展(例如,使用引导的CDI容器),那么将有两个选项;要么重新加载整个CDI容器以考虑此扩展,要么完全忽略其内容,使其完全无用,因为它将充当普通bean(容器生命周期观察者永远不会被调用)。前者在某些部署中会非常昂贵/令人不安,并可能导致不可预测的结果——想象一下,这种动态扩展会与替代方案和专业化混在一起。后一种情况毫无意义,因为它会添加一个从未使用过的bean。这就是为什么CDI一般不允许这样做


我想知道,你的用例是什么?如果我们知道这一点,也许我们可以用另一种方式帮助您解决这个问题。

简单回答一下-CDI故意不提供API来动态添加扩展。事实上,你不应该试图做到这一点

一点原因:

CDI本质上是静态的——它在引导过程中需要某些信息,扩展就是其中之一。一旦引导完成,扩展大部分就变得无用了(当然,您仍然可以将它们作为bean使用,并且在那里有一些逻辑,但是它只是一个bean)。原因是扩展钩住了引导循环,并且可以影响每个阶段(
ProcessAnnotatedType
ProcessBeanAttributes
,…)

现在,如果您稍后以某种方式加载了这样一个扩展(例如,使用引导的CDI容器),那么将有两个选项;要么重新加载整个CDI容器以考虑此扩展,要么完全忽略其内容,使其完全无用,因为它将充当普通bean(容器生命周期观察者永远不会被调用)。前者在某些部署中会非常昂贵/令人不安,并可能导致不可预测的结果——想象一下,这种动态扩展会与替代方案和专业化混在一起。后一种情况毫无意义,因为它会添加一个从未使用过的bean。这就是为什么CDI一般不允许这样做


我想知道,你的用例是什么?如果我们知道这一点,也许我们可以用另一种方式帮您解决。

Thx。同意加载它并在逻辑中添加一个切换的简单解决方案,与那些相比听起来不错!谢谢。同意加载它并在逻辑中添加一个切换的简单解决方案,与那些相比听起来不错!谢谢在我的用例中,另一个答案是,获得控制权,然后保护逻辑,以便在发现其他属性之前进一步调用。我很好奇这是否真的是设计意图,所以接受这个答案,因为它解决了这个问题。一个用例是只在特殊情况下为
processAnnotatedType
添加一个观测者,而不使用
@WithAnnotations
,例如,仅当在泽西岛定义了
Hk2CustomBoundTypesProvider
时。谢谢。在我的用例中,另一个答案是,获得控制权,然后保护逻辑,以便在发现其他属性之前进一步调用。我很好奇这是否真的是设计意图,所以接受这个答案,因为它解决了这个问题。一个用例是仅在特殊情况下,例如仅在泽西岛的
Hk2CustomBou中,为
processAnnotatedType
添加一个观察员,而不使用
@WithAnnotations