我们有一个使用Spring(3.0.5)和CXF的Web应用程序(目前由于各种原因而为2.4.2,但如果有任何不同,则升级是一个选项)并部署在Tomcat上。
使用 org.springframework.web.context.ContextLoaderListener 初始化应用程序。
启动和关闭应用程序就像魅力一样,但如果我尝试刷新Spring应用程序上下文,请使用
((ConfigurableApplicationContext)applicationContext).refresh();
我遇到了问题。应用程序上下文首先销毁其所有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一切正常。
答案 0 :(得分:0)
我认为你不能告诉CXF不要那样工作。但是,您可以做的是将需要重新启动的应用程序部分隔离到您构建的自己的上下文中,并在不涉及主要上下文的情况下拆除。也许你会用ClassPathXmlApplicationContext
做到这一点,尽管有一些选择。我认为你将外部上下文设置为内部的父项,并引用外部bean XML-config syntax,如:
<ref parent="foo" />
然后,您需要创建一些方法,将外部上下文中的CXF代理活动到内部上下文中的bean。这是一个棘手的部分,因为它通常被认为是引用的错误形式。您可能必须在(相关的)内部bean连接到外部上下文中的某种注册表/代理作为其创建/初始化过程的一部分(并从拆除时取消注册)。您还必须决定如何处理在没有内部上下文时需要提供请求的情况。整蛊,特别是如果你想优雅地做到这一点......