当前位置: 首页 > 知识库问答 >
问题:

如何注入存在于另一个类加载器中的CDI托管bean

麻华辉
2023-03-14

我正在开发一个将在JavaEE应用程序中使用的框架,因此很可能部署在EAR文件的\lib目录中。

该框架将使用CDI以编程方式查找和注入位于使用该框架的JavaEE应用程序中的bean。我遇到的问题是,提供程序。从javax获取()方法。企业供应商

为了检查这不是一个与CDI相关的问题,我还尝试使用MyClass myClass=Class.forName(clazz). newInstance();来获取类的实例,但是抛出了ClassNotFoundExc0019

我用于测试目的的EAR文件的结构如下:

MyTestApp.ear
+\lib\MyFramework.jar <----Contains the framework invoking the Provider.get() method
+MyTestApp.jar        <----Contains the bean I want to inject

我的测试应用程序的EAR包含一个application.xml文件,其中包含

我认为出现这个问题是因为我想要注入的bean存在于一个单独的类加载器中。i、 e.\lib\MyFramework。jar与MyTestApp位于不同的类加载器中。jar。我发现这个问题似乎表明情况就是这样。考虑到我正在开发一个框架,我不相信这个问题的答案是满足我需求的可行解决方案。

我很想知道创建一个CDI可移植扩展是否能让我得到一个我想要使用的bean实例,但我在这方面没有足够的经验。使用@ProcessAnnotatedType

我的问题是:

>

  • 我假设发生此问题是因为\lib\MyFramework,对吗。jar和MyTestApp。jar是否在单独的类加载器中?

    我可以使用CDI做任何事情,当部署在EAR文件的\lib目录中时,允许我的框架进行Provider.get()方法调用,以避免Weld抛出未满足的解决方案

    除了CDI,我还能做些什么来达到同样的效果吗?

    使现代化

    我现在尝试移动MyFramework。jar到EAR文件的根目录,并在应用程序中包含jar模块。xml文件,但由于CDI未满足依赖项异常,容器无法启动应用程序。异常中引用的bean可以在MyFramework时被注入。jar位于\lib目录中,与我的问题中引用的bean不同。


  • 共有2个答案

    袁翰池
    2023-03-14

    在我看来,让“框架”依赖于应用程序实现可能是一个糟糕的体系结构决策。也许您的应用程序应该实现一些框架级接口来实现您的目标。正如您所拥有的或希望它工作的那样,这表明您ear中的一个应用程序,任何真正的应用程序,都可以通过向框架提供实现来影响您ear中所有其他应用程序的操作。这对我来说似乎是个坏主意。而且,如果您能够实现这一点,并且ear中有多个应用程序提供了这一实现,那么CDI仍然可能会因为不明确的依赖关系而失败。

    虽然以上可能行得通,但经过思考,我认为这也是一个坏主意。你真的应该认真看看你真正想做的事情。我认为如果你更仔细地看看你正在尝试做什么,你会发现你可能能够剥离或抽象一些依赖,并且仍然为框架提供实现,但不是从耳朵里的应用程序。

    郏经纬
    2023-03-14

    1:是的

    2:其实我不知道

    3:是的,您必须了解ear类加载器层次结构,ear lib目录中的JAR是在ear级别加载的,因此在所有子类加载器中都可用(ear中每个组件有一个子类加载器)。

    这意味着我的框架。jar在MyTestApp中可见。jar ear子类加载器,但反向为false。

    在JavaEE中,我应该将哪些JAR放在库目录中?

    您可以:

    • 移动MyTestApp.jar到耳lib目录(MyFramework.jar可以在lib目录和引用MyTestApp.jar或在耳根)
    • 移动MyFramework.jar在耳根和参考MyTestApp.jar在其清单类路径

    请参见在一个EAR中部署多个依赖的CDI罐

     类似资料:
    • 在我正在构建的应用程序中,我们使用直Java6 EE和JBoss(没有Spring等),以及JPA/Hibernate、JSF、CDI和EJB。 我还没有找到很多好的通用安全解决方案(欢迎推荐),但我找到的最佳选择是ApacheShiro。 然而,这似乎有一些缺点。您可以在Balus C的网站上阅读其中一些内容: http://balusc.blogspot.com/2013/01/apache-

    • 问题内容: 我试图通过注释将整个JSF托管Bean注入另一个托管Bean非常相似,但是我正在注入Bean,而不是Servlet)。这就是我在做什么: 不起作用(JSF 2.0 / Mojarra 2.0.3): 有没有可能或者我需要通过编程方式进行注射? 问题答案: 您需要添加setter和getter 当将解析并注入依赖项时,它将使用setters注入,因此适当的setters / getter

    • 我有一个类,它实现了接口。类由system classloader加载,接口在第三方组件中定义,我认为第三方组件将接口加载到另一个类加载器(动态类加载器)中。 当我试图创建的新实例时,我得到的是的。我想这是因为它是由不同的类加载器加载的。 我尝试创建(与Guice使用的类似),然后从system类加载器加载类,并从另一个类加载器加载所有其他类,我认为这是用于的类加载器,但没有成功。 有办法绕过它吗

    • 我正在用CDI开发一个库。这个很好用。但是,当我试图将这个库用作项目中包含的Jar时,CDI抱怨说它无法解决对父项目中定义的托管bean的依赖关系。 MyProject-MyLib。jar-MyManagedBean 所以MyLib需要注入一个带有原型@foo注释的bean。此原型应用于MyManagedBean。 我加了豆子。我的父项目也使用xml。但好像有两个不同的CDI容器,MyLib无法访

    • 问题内容: 我是Angular的新手,正在尝试弄清楚该怎么做… 使用AngularJS,如何注入要在另一个控制器中使用的控制器? 我有以下片段: 执行此操作时,出现错误: 我是否应该尝试在另一个控制器内部使用一个控制器,还是应该将此服务用作服务? 问题答案: 如果您打算掌握已经实例化的另一个组件的控制器,并且如果您遵循的是基于组件/指令的方法,则始终可以遵循某个层次结构的另一个组件中的控制器(一个

    • 我试图以编程方式查找并注入一个CDI托管bean,其中限定符包含一个类的名称(不是我想要注入的类),但是我遇到的问题是,我用来查找正确bean的代码总是返回。 我要注入的bean使用名为的自定义注释进行注释,该注释包含用作限定符的类的名称,bean还实现了名为的接口。我使用的类实现了接口。 基于我对CDI的有限了解,我认为为了以编程方式查找使用注释限定的正确bean,我需要扩展,然后我可以使用来选