4

关于上述类,我有一些集成问题,但仅限于“太新”的 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' Spring 版本: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

4

1 回答 1

4

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

processInjectionBasedOnCurrentContext(this);

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

于 2012-11-26T08:53:03.753 回答