cxf和spring整合注入值為NULL問題
阿新 • • 發佈:2019-01-22
用cxf+spring開發web service程式很簡單,不過有一些整合問題要注意。
1、關於bean的宣告
要釋出或者要呼叫的web service介面,需要用@WebService註解宣告。不過要注意的是,@WebService註解不會把類宣告為spring的bean
可以宣告為bean的方式有以下4個:
<jaxws:endpoint>
<jaxws:client>
<bean id="" class="">
@Component
寫了一個類來證明這一點:
Java程式碼
在控制檯可以看到以下幾個bean:
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) helloWorldImpl
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) helloWorld
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) remedy
以上3個bean,就分別是由<bean>、<jaxws:endpoint>、<jaxws:client>生成的
2、如果要在<jaxws:endpoint>的實現類中注入bean的話,要注意:
錯誤的寫法:
Xml程式碼
用這種寫法,雖然HelloWorldImpl類已經被宣告成bean了,但是注入是失敗的
準確來說,在spring容器中存在有HelloWorldImpl對應的bean,並且相關的依賴也已經注入了。但是cxf框架得到的HelloWorldImpl,與上述的bean不是同一個物件,這個HelloWorldImpl物件可能是用反射或者其他機制創建出來的,沒有任何元件被注入
正確的寫法:
Xml程式碼
在implementor屬性中,用#beanName,這樣的話,cxf框架得到的HelloWorldImpl,就是spring容器持有的那個bean。當然這有個前提,就是系統中已經存在這個bean。用<bean id="">或者@Component都是OK的,這裡支援註解
3、上面說的是<jaxws:endpoint>,比較簡單。但是<jaxws:client>就比較麻煩
我目前感覺,<jaxws:client>宣告的bean,沒辦法在別的bean裡用@Autowired注入,只能用<bean id="">的方式來注入
Java程式碼
Java程式碼
用這種<bean id="">的方式就可以
Java程式碼
1、關於bean的宣告
要釋出或者要呼叫的web service介面,需要用@WebService註解宣告。不過要注意的是,@WebService註解不會把類宣告為spring的bean
可以宣告為bean的方式有以下4個:
<jaxws:endpoint>
<jaxws:client>
<bean id="" class="">
@Component
寫了一個類來證明這一點:
Java程式碼
-
protected void doGet(HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
- ServletContext context = request.getServletContext();
- WebApplicationContext wc = WebApplicationContextUtils
- .getWebApplicationContext(context);
-
String[] beans = wc.getBeanDefinitionNames();
- for (String beanName : beans) {
- System.out.println(beanName);
- }
- RemedyWebServiceCM remedy = (RemedyWebServiceCM) wc.getBean("remedy");
- AcknowledgeRequest message = new AcknowledgeRequest();
- remedy.acknowledge(message);
- }
在控制檯可以看到以下幾個bean:
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) helloWorldImpl
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) helloWorld
20:02:24,120 INFO [stdout] (http--0.0.0.0-8888-2) remedy
以上3個bean,就分別是由<bean>、<jaxws:endpoint>、<jaxws:client>生成的
2、如果要在<jaxws:endpoint>的實現類中注入bean的話,要注意:
錯誤的寫法:
Xml程式碼
- <jaxws:endpoint id="helloWorld" address="/HelloWorld"
- implementor="com.huawei.framework.webservice.HelloWorldImpl" />
用這種寫法,雖然HelloWorldImpl類已經被宣告成bean了,但是注入是失敗的
準確來說,在spring容器中存在有HelloWorldImpl對應的bean,並且相關的依賴也已經注入了。但是cxf框架得到的HelloWorldImpl,與上述的bean不是同一個物件,這個HelloWorldImpl物件可能是用反射或者其他機制創建出來的,沒有任何元件被注入
正確的寫法:
Xml程式碼
- <jaxws:endpoint id="helloWorld" address="/HelloWorld"
- implementor="#helloWorldImpl" />
在implementor屬性中,用#beanName,這樣的話,cxf框架得到的HelloWorldImpl,就是spring容器持有的那個bean。當然這有個前提,就是系統中已經存在這個bean。用<bean id="">或者@Component都是OK的,這裡支援註解
3、上面說的是<jaxws:endpoint>,比較簡單。但是<jaxws:client>就比較麻煩
我目前感覺,<jaxws:client>宣告的bean,沒辦法在別的bean裡用@Autowired注入,只能用<bean id="">的方式來注入
Java程式碼
- @WebService
- public interface RemedyWebServiceCM {
- RemedyResponse acknowledge(AcknowledgeRequest arg0);
- RemedyResponse close(CloseRequest arg0);
- RemedyResponse notify(NotifyRequest arg0);
- }
Java程式碼
- public class HelloWorldImpl implements HelloWorld {
- private RemedyWebServiceCM remedy;
- public String sayHi(User theUser) {
- AcknowledgeRequest message = new AcknowledgeRequest();
- remedy.acknowledge(message);
- return "Hello " + theUser.getName() + " ,your age is "
- + theUser.getAge();
- }
- public void setRemedy(RemedyWebServiceCM remedy) {
- this.remedy = remedy;
- }
- }
用這種<bean id="">的方式就可以
Java程式碼
- @Controller
- public class HelloWorldImpl implements HelloWorld {
- @Autowired
- private RemedyWebServiceCM remedy;
- public String sayHi(User theUser) {
- AcknowledgeRequest message = new AcknowledgeRequest();
- remedy.acknowledge(message);
- return "Hello " + theUser.getName() + " ,your age is "
- + theUser.getAge();
- }
- }