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