WSServletContainerInitializer和SpringBeanAutowiringSupport

时间:2012-10-09 18:00:25

标签: spring jax-ws tomcat7

我对所提到的类有一些集成问题,但只有“太新”的tomcat版本。

基础设置: 的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="FooService" version="2.5" metadata-complete="true">

    <display-name>FooService</display-name>

    <servlet>
        <servlet-name>jax-ws</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
</web-app>

FooServiceImpl:

@WebService(serviceName = ServiceInfo.SERVICENAME, targetNamespace = ServiceInfo.TARGETNAMESPACE, endpointInterface = "bar.FooService")
@HandlerChain(file = "/handler-chain.xml")
public class FooServiceImpl extends SpringBeanAutowiringSupport implements FooService {

    @Autowired
    private Bar bar;

    << some methods using the injected bar singleton >>

JAX-WS依赖:编译'com.sun.xml.ws:jaxws-rt:2.2.7' 春季版:3.1.2.RELEASE

使用Tomcat 7.0.22我没有问题。 web.xml中声明的webapp版本是2.5。 Tomcat 7.0.22不处理WSServletContainerInitializer。因此,在web.xml中声明,首先初始化ContextLoaderListener,因此WebApplicationContext中将提供Bar的实例。然后WSServletContextListener实例化FooServiceImpl,一个令人愉快的工作,每个人都很高兴。

但是......我的同事用Tomcat 7.0.30尝试了它并且自动装配不起作用(7.0.32给出了同样的问题,目前这是最新的)。它实际上无法工作,因为新的Tomcat版本已经处理了WSServletContainerInitializer,没有考虑2.5 webapp版本(和metadata-complete =“true”)。

我找到了一个可能的解决方案。我注释掉了web.xml的主体,将webapp版本更改为3.0并创建了一个WebapplicationInitializer:

public class MyInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        ContextLoader loader = new ContextLoader();
        loader.initWebApplicationContext(servletContext);
    }

}

这对我来说非常合适。但不是我的同事......如果他试图运行应用程序,首先会激活WSServletContainerInitializer,它会产生与上面完全相同的布线问题。

显然,我们可以“破解”摆脱SpringBeanAutowiringSupport并从getter或web方法或任何类似方式手动注入Bar的问题。但是SpringBeanAutowiringSupport会更加清晰,所以如果有一个很好的解决方案可以解决上述问题,我们可以使用它。

更新:这会导致问题:https://issues.apache.org/bugzilla/show_bug.cgi?id=53619

1 个答案:

答案 0 :(得分:4)

对我来说,解决方案是在自动装配的引用为空时调用以下内容

processInjectionBasedOnCurrentContext(this);

我希望它对所有人都有帮助。