TLDR at the bottom:
As per the JBossWS-cxf user guide, for a web service, the web.xml should contain the following
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>MyWebService</servlet-name>
<servlet-class>com.sgb.MyWebService</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyWebService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Jboss also expects a descriptor file named jboss-cxf.xml in WEB-INF directory (instead of cxf.xml) which should contain the jaxws:endpoint tag like so:
<beans xmlns='http://www.springframework.org/schema/beans'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:beans='http://www.springframework.org/schema/beans'
xmlns:jaxws='http://cxf.apache.org/jaxws'
xsi:schemaLocation='http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://cxf.apache.org/jaxws >
<bean id="MyWebService" class="com.sgb.MyWebService" />
<jaxws:endpoint id="POJOEndpoint" implementor="#MyWebService" wsdlLocation="WEB-INF/wsdl/XYZ.wsdl" address="/warfilename">
<jaxws:invoker>
<bean class="org.jboss.wsf.stack.cxf.InvokerJSE" />
</jaxws:invoker>
</jaxws:endpoint>
</beans>
I then create my service implementation class thusly:
package com.sgb;
@javax.jws.WebService(... ... ... )
public class MyWebService implements IMyWebService
{
public CreateResponse create(CreateRequest request)
{
... ... ... <-- an instance of createService is created
return createService.serve(request)
}
}
So far so good. It works fine.
However, as per Spring's reference documentation, the convenient way to instantiate an application context for web applications is by adding a ContextLoaderListener in the web.xml like so.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
So, I could add the above in my web.xml and then annotate MyWebService class with @Service and make sure the package is set up for component-scaning. And it should become a spring managed bean too.
Problem is, it doesn't. JbossWS-CXF seems to be instantiating MyWebService due to which the dependencies are not injecte resulting in a nullpointer.
I am able to get the applicationContext programmatically using ClassPathXmlApplicationContext("/WEB-INF/applicationContext.xml")
And then inject/create my dependencies using appContext.getBean()
But I was hoping to inject/autowire the dependencies directly using annotations instead.
TLDR:
What I currently have is this. (This bean is created by jboss and not spring):
@javax.jws.WebService(... ... ... )
public class MyWebService implements IMyWebService
{
private ApplicationContext appContext;
public MyWebService(){
appContext = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext-ws.xml");
}
public CreateResponse create(CreateRequest request)
{
*** Use getBean() here to get my dependency. ***
IXyzService createService = appContext.getBean("createService",IXyzService.class);
return createService.serve(request)
}
}
What I want is this:
@javax.jws.WebService(... ... ... )
@Service <-- <-- <-- ** This is Spring managed bean**
public class MyWebService implements IMyWebService
{
@Resource <-- <-- <-- **Dependency Injected by Spring**
IXyzService createService;
public CreateResponse create(CreateRequest request)
{
return createService.serve(request)
}
}
What is the best way to accomplish this ???