我假设您的意思是独立部署或在不同 EAR 中部署的单独 WAR。
请记住,CXF 是内置在 JBoss 中的,所以也许您不需要这种动态注册 - 如果它只是关于配置。
不幸的是,您无法使用单独的 WAR 轻松进行此类动态注册。我做了一些研究。
首先,为了完成这项工作,CXF 库必须从 JBoss 库中加载,而不是从您的 web 应用程序的 lib 目录中加载。这是因为 WAR 有单独的类加载器。加载类时,这些类加载器会咨询它们的父类,但不会咨询其他 WAR 类加载器。即使两个 WAR 都嵌入了 CXF jar,生成的类也会不兼容 - 类加载器 A 加载的 CXFServlet 类与类加载器 B 加载的 CXFServlet 类不同,即使这两个类都是从同一个 JAR 加载的。
要使用 JBoss 嵌入式 CXF,您需要将 jboss-deployment-structure.xml 添加到 WEB-INF,内容如下:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.apache.cxf" services="import">
<imports>
<include path="**" />
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>
要运行需要spring框架的CXFServlet,您还需要将spring jars添加到JBoss安装中并将它们定义为模块,如下所述:How can I use the external jars on JBoss 7?。还需要添加 jboss-deployment-structure.xml 中的依赖项。
如果你让它运行起来(恭喜,我没能做到:/)那么你可以尝试使用org.apache.cxf.BusFactory.getDefaultBus()返回的默认总线。例如,带有 CXFServlet 的主 WAR 可能会设置此默认总线,而其他模块可能能够检索到此总线。但我有 99% 的把握,不是从 CXF 获得 BusFactory,而是得到一些 org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory。这个被 JBoss “加强”了,所以你将无法检索共享总线对象,但 each thread 的另一个对象是不同的。要更改这一点,您应该在每个 WAR 中创建以下文件:META-INF/services/org.apache.cxf.bus.factory,内容为:org.apache.cxf.BusFactory。这应该能够用默认的 CXF 覆盖 JBoss 总线工厂。
好的,现在我们应该可以检索公共总线了。我还没有测试过,但是使用 Bus 你应该能够添加新服务。没有明显的 API,但也许这样的东西会起作用:bus.getExtension(WSDLManager.class).addDefinition(implementor, definition);。
呃,如您所见,这只是潜在解决方案的草图。有太多事情可能出错。这项任务并不容易,而且肯定很痛苦。
您也可以尝试使用 JBoss 7 支持的 OSGi。您安装捆绑包,它们会发布一些端点。 JBoss 上对 OSGi 的一些介绍可以在here 找到。 here 是一些提示如何在 JBoss 上使用 CXF 和 OSGi。但同样,这不是很流行的 JBoss 使用方式,所以不要期望得到太多支持。
编辑:
为什么cxf.xml 文件的自动发现不起作用,您可能也很感兴趣。 CXFServlet 正在使用currentClassloader.getResourceAsStream(..) 来检查cxf.xml 是否存在。如果 cxf.xml 在不同的 WAR 中,则当前的类加载器无法找到它。