使用CXF时如何刷新Spring上下文?
我们有一个使用 Spring (3.0.5) 和 CXF(由于各种原因目前为 2.4.2,但如果有任何区别的话可以选择升级)的 Web 应用程序,并部署在 Tomcat 上。
该应用程序使用 org.springframework.web.context.ContextLoaderListener 进行初始化。
启动和关闭应用程序就像一个魅力,但如果我尝试使用
((ConfigurableApplicationContext)applicationContext).refresh();
刷新 Spring 应用程序上下文,我会遇到问题。应用程序上下文首先销毁其所有bean(包括CXFBusImpl,或者更确切地说是其子类SpringBus)。然而,SpringBus 在其应用程序上下文上调用 close() - 当应用程序上下文不久后尝试关闭其 bean 工厂时,会导致 NullPointerException:
java.lang.NullPointerException
at org.springframework.context.support.AbstractRefreshableApplicationContext.closeBeanFactory(AbstractRefreshableApplicationContext.java:152)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:124)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
我可以做些什么来避免这种情况(除了修改 CXF 之外)?如果我跳过 CXF 一切正常。
We have a web application that uses Spring (3.0.5) and CXF (currently 2.4.2 for various reasons but upgrading is an option if that makes any difference) and is deployed on Tomcat.
The application is initialized using the org.springframework.web.context.ContextLoaderListener.
Starting and shutting the application down works like a charm but if I try to refresh the Spring application context, using
((ConfigurableApplicationContext)applicationContext).refresh();
I run into problems. The application context first destroys all its beans (including CXFBusImpl, or rather its subclass SpringBus). SpringBus however calls close() on its application context - leading to a NullPointerException when the application context shortly after tries to close its bean factory:
java.lang.NullPointerException
at org.springframework.context.support.AbstractRefreshableApplicationContext.closeBeanFactory(AbstractRefreshableApplicationContext.java:152)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:124)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
Is there anything I can do to avoid this (other than modifying CXF)? If I skip CXF everything works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你不能告诉 CXF 不要那样工作。不过,您可以做的是将应用程序中需要重新启动的部分隔离到您自己构建和拆除的上下文中,而无需过多涉及主上下文。也许你会用
ClassPathXmlApplicationContext
,尽管有几个选择。我认为您会将外部上下文设置为内部上下文的父级,并使用 XML-config 语法 如下:然后,您需要创建某种代理活动的方法CXF 位于 Bean 的外部上下文中内部背景。这是棘手的部分,因为这样的引用通常被认为是不好的形式。您可能必须在外部上下文中拥有某种注册表/代理,(相关的)内部 bean 作为其创建/初始化过程的一部分连接到(并在拆卸时取消注册)。您还必须决定如何处理在没有内部上下文的情况下需要服务请求的情况。很棘手,尤其是如果你想优雅地做到这一点......
I don't think you can tell CXF not to work that way. What you could do though is to isolate the parts of your application that need restarting into their own context that you build and and tear down as you choose without involving the main context over much. Perhaps you'd do that with a
ClassPathXmlApplicationContext
, though there are a few choices. I think you'll be setting the outer context as the parent of the inner, and referring to outer beans with XML-config syntax like:You'll then need to create some way of proxying the activity with CXF in the outer context to the beans in the inner context. This is the tricky part, as it is usually considered bad form for references to go that way round. You'll probably have to have some kind of registry/proxy in the outer context that (relevant) inner beans connect to as part of their creation/init process (and deregister from at tear-down). You'll also have to decide how to handle the case where a request needs to be served when there is no inner context. Tricky, especially if you want to do it elegantly...