运行时的 JSR-299 (CDI) 配置
我需要为不同的运行时环境(例如测试、登台和生产服务器)配置不同的 @Alternatives、@Decorators 和 @Injectors。
现在我使用 maven 创建三个 war,这些 war 之间的唯一区别在于 beans.xml 文件。有更好的方法吗?我确实有针对不同环境的 @Alternative @Stereotypes,但即便如此,我也需要更改 beans.xml,并且它们不适用于 @Decorators(或者它们吗?)
是否可以以某种方式指示 CDI 忽略中的值beans.xml 并使用自定义配置源?因为这样我就可以读取系统属性或其他环境变量。
该应用程序专门在使用 Weld 的容器中运行,因此特定于焊接的解决方案就可以了。
我已经尝试用谷歌搜索这个,但似乎找不到好的搜索词,我问了 Weld-Users-Forums< /a>,但无济于事。那里有人建议编写我自己的自定义扩展,但我找不到任何 API 来在运行时实际更改容器配置。
我认为可以有某种 @ApplicationScoped 配置 bean 并将其注入到所有 @Decorators 中,然后 @Decorators 可以自行决定它们是否应该处于活动状态,然后为了配置 @Alternatives 为每个接口编写 @Produces 方法多个实现并在那里注入配置 bean。 但在我看来,这似乎是大量不必要的工作,本质上是重复 CDI 中已有的功能?
编辑
好吧,我意识到我有点愚蠢......当然可以使用 CDI 扩展 API 在运行时添加构造型和拦截器:
void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
bbd.addInterceptorBinding(...)
bbd.addStereotype(...)
}
但我没有找到一个 API添加装饰器。我发现的唯一的事情是激活 beans.xml 中的所有 @Decorator,然后观察
public <T> void processAnotated(@Observes ProcessAnnotatedType<T> event)
并调用
event.veto()
是否我不希望 @Decorator 处于活动状态。
I need to configure different @Alternatives, @Decorators and @Injectors for different runtime environments (think testing, staging and production servers).
Right now I use maven to create three wars, and the only difference between those wars are in the beans.xml files. Is there a better way to do this? I do have @Alternative @Stereotypes for the different environments, but even then I need to alter beans.xml, and they don't work for @Decorators (or do they?)
Is it somehow possible to instruct CDI to ignore the values in beans.xml and use a custom configuration source? Because then I could for example read a system property or other environment variable.
The application exclusively runs in containers that use Weld, so a weld-specific solution would be ok.
I already tried to google this but can't seem to find good search terms, and I asked the Weld-Users-Forums, but to no avail. Someone over there suggested to write my own custom extension, but I can't find any API to actually change the container configuration at runtime.
I think it would be possible to have some sort of @ApplicationScoped configuration bean and inject that into all @Decorators which could then decide themselves whether they should be active or not and then in order to configure @Alternatives write @Produces methods for every interface with multiple implementations and inject the config bean there too.
But this seems to me like a lot of unnecessary work to essentially duplicate functionality already present in CDI?
edit
Ok, I realized I'm a bit stupid... of course it is possible to add stereotypes and inteceptors at runtime using the CDI extension API:
void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
bbd.addInterceptorBinding(...)
bbd.addStereotype(...)
}
But what I didn't find was an API to add a decorator. The only thing I found was to activate all @Decorators in the beans.xml, then observe
public <T> void processAnotated(@Observes ProcessAnnotatedType<T> event)
and call
event.veto()
if I don't want a @Decorator to be active.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能想看看 JBoss Seam,特别是 Solder 子项目。
它允许依赖驱动的 CDI 解析,因此某些 Bean 仅在其他 Bean 或资源可用时才可用。 (如果“dataSource”可用,则为 A 类;如果“entityManager”可用,则为 B 类)
由于它是开源的,您还可以看看他们如何将它们连接在一起,并使用这些知识作为编写您自己的扩展的基础,如果需要。
如果您使用 JSF,我强烈建议您也使用 SEAM-JSF,因为它摆脱了两个注入框架 (JSF DI/CDI) 的笨重,并允许在 JSF 范围内使用 CDI bean。
You might want to take a look at JBoss Seam, specifically the Solder sub-project.
It allows dependency driven CDI resolution, so that certain beans are only available if other beans or resources are available. (Class A if "dataSource" is available, Class B if "entityManager" is available)
Since it's open source, you can also take a look at how they wired that together, and use that knowledge as a basis for writing your own extension if needed.
If you're using JSF, I would highly recommend using SEAM-JSF as well, as it gets rid of the clunkiness of having two injection frameworks (JSF DI/CDI) and allows CDI beans in JSF scopes.