【问题标题】:Resolution of external (3rd party) beans in weld焊接中外部(第 3 方)bean 的分辨率
【发布时间】:2011-01-16 21:51:14
【问题描述】:

我知道它仍然不太受欢迎,因为该规范是在几个月前发布的。

我还没有“安装”weld,我只是在阅读,通过这个问题,我想确保我已经正确理解了这一点:

是否通过在您的beans.xml 中将它们声明为<alternatives> 来实现对 3rd-party jar 中的 bean 的解析?

如果没有,如何使用来自没有 beans.xml 的 3rd 方库中的 bean?

除非在他们的META-INF 中有beans.xml,否则将 jar 放在类路径上是行不通的,对于 3rd 方 jar,你不能做到这一点。 (见Gavin King's post on the subject

【问题讨论】:

    标签: java cdi jboss-weld jsr299


    【解决方案1】:

    我对 alternative 的理解是,它是您可以在不同部署环境(例如测试环境)中使用的接口的其他实现的替代方案。 alternative bean 是通过使用@Alternative 注释来声明的。

    要在给定部署方案中使用替代方案,请在 CDI 部署描述符 META-INF/beans.xml<alternatives> 元素中选择它。这将启用默认禁用的 @Alternative bean。

    启用后,如果容器发现给定注入点的不明确依赖项,它将查看可以注入的替代方案,如果确实有一个,则选择该替代方案。

    换句话说,alternatives 是在部署时用另一个实现替换现有实现 的好方法。如果没有什么可替换的,你不需要替代品,只需将你的 jar 放在类路径上。不确定这是否正是您的问题,我对 3rd-party jars 的概念有疑问。

    2.1.4. Alternatives4.6. Alternatives4.7. Fixing unsatisfied and ambiguous dependencies 中的更多内容(但我猜这就是您正在阅读的内容)。

    更新:回答您的其他问题。

    如果没有,如何使用没有 beans.xml 的 3rd 方库中的 bean

    这不可能发生,bean 存档必须有一个bean.xml(可以是空的),如文档的15.6. Packaging and deployment 部分所述:

    CDI 没有定义任何特殊的 部署存档。你可以打包 JAR、EJB-JAR 或 WAR 中的 bean——任何 应用程序中的部署位置 类路径。但是,存档必须 成为“豆档案”。这意味着每个 包含 bean 的存档必须 在 META-INF 类路径的目录或 WEB-INF Web 根目录(对于 战争档案)。该文件可能为空。 部署在档案中的 Bean 有beans.xml 文件不会 可在应用程序中使用。

    然后,要修复不满足和不明确的依赖关系,请参阅前面提到的 4.7 节。

    更新 2: 使用 BeforeBeanDiscovery.addAnnotatedType() 似乎可以添加其他类以在 bean 发现期间考虑。 (BeforeBeanDiscovery 是一个事件)

    【讨论】:

    • 啊哈,所以不是这个。不幸的是,在类路径中放置一个 jar 是行不通的,除非你在其中有一个 beans.xml - 请参阅 Gavin King 的博文 - relation.to/Bloggers/WhyIsBeansxmlRequiredInCDI 我正在尝试查看如何使用不在 bean 档案中的 3rd 方对象.
    • 所以,如果你想使用,比方说,c3p0 连接池,他们(或你)必须将beans.xml 放入 jar 中,否则你将无法与 DI 一起使用它?
    • @Bozho 是的,beans.xml 对于“bean 存档”是强制性的,否则应用程序将无法使用bean,如文档所述(当您发布评论时正在更新我的答案)。当我在最初的回答中写“把它放在类路径上”时,我没有明确提到它,但它是暗示的:)
    • 谢谢。顺便说一句,这对我来说听起来很糟糕。我认为这迟早会成为一项要求。 (顺便说一句,我正在阅读它,因为我计划提供 JSR299 的部分实现作为我的毕业项目。在那里我可能会提供一些使用外部 bean 的非标准方式:))
    • @Bozha 想出所有可能的用例并不容易,但这确实是我的理解。实际上,我想知道 CDI 对图书馆的影响是什么,它打开了什么样的大门(这仍然是新事物)。也许现在包装 bean 可以解决问题。
    【解决方案2】:

    为什么想得这么复杂?

    只需为这些 3rd 方类创建一个 producerMethod。

    假设您有一个第三方库,它会自动获取 PDF 文件并按传真发送它们,并且您喜欢使用类似的东西

    private @Inject PdfFaxService faxService;
    

    在您的代码中,您可以简单地为它提供一个生产者方法。 PdfFaxService 是无状态的,所以我们可以放心地假设我们可以让它@ApplicationScoped

    public @Produces @ApplicationScoped PdfFaxService createFaxService() {
      return new PdfFaxService(initparameters);
    }
    

    某处。

    第一次。

    【讨论】:

    • 除了定义生产者方法之外,真的没有其他办法了吗?当这样一个简单的用例(即,使来自 3rd 方 jar 的 bean 成为托管 bean 并且能够被注入)需要所有这些额外的工作时,我有时真的不明白一些设计师的想法。 .似乎 beans.xml 将是此配置的理想位置,但它只有一个“排除”元素而不是“包含”...真的吗???
    • 这是 2 行严格类型的代码。因此,如果您搜索类型用法,您会在您的 IDE 中看到这一点,当时您在大多数 IDE 中都有完美的 CDI 支持,等等。所以我真的更喜欢它而不是 2 行无类型 XML。你有没有遇到过这样 600 行的 XML 怪物,没人能再准备好(实际上 80% 是不需要的)?
    • 这是您希望能够管理的每个类的 2 行代码,在第三方 jar 的情况下,可以有很多,例如 100+。 XML 可以非常简单:即 。那是一行可选的 XML(现有的发现仍然可以以相同的方式工作),可能包含来自 JAR 文件的更多类,这些类不是用 beans.xml 构建的,而不是像你暗示的那样 600。抱歉,我还是不明白你的意思。
    • @GreenieMeanie 您也可以使用 CDI 扩展轻松做到这一点。只需为符合您需要的每个扫描类动态添加一个 Bean(请参阅 ProcessAnnotatedType 和 AfterBeanDiscovery)。或者为没有 beans.xml 的 jar 配置类名 + 使用 AfterBeanDiscovery#addBean
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多