【问题标题】:Spring bean not injected into CXF web service, Why?Spring bean 没有注入到 CXF Web 服务中,为什么?
【发布时间】:2012-05-14 10:16:55
【问题描述】:

我正在编写一个 RESTful 服务(在 JBoss 上使用 CXF),其中我使用 Spring(Autowired)注入了另一个类。但是该类没有被注入并且为空。

Web 服务接口和类(需要进行注入的地方)

package com.company.project.web;

@Path("/myws")
public interface IMyWebService {    
   @POST
   @Path("/doSomething")    
   @Consumes("application/json")
   @Produces("application/json")
    MyResponse doSomething(MyRequest myRequest)
}

@Service("myWebService")
public class MyWebService implements IMyWebService {    
    @Autowired
    private IMyCore myCore;

    public MyResponse doSomething(MyRequest myRequest) {
      ....
    }
}

必须注入的东西

package com.company.project.biz;

public interface IMyCore {
   MyResponse doSomething(MyRequest myRequest);
}

@Component("myCore")
public class MyCore implements IMyCore {
    public MyResponse doSomething(MyRequest myRequest) {
            .....
    }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd    
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

    <context:annotation-config />
    <context:component-scan base-package="com.company.project"/>    

    <jaxrs:server id="myWebService" address="/">
        <jaxrs:serviceBeans>
            <bean class="com.company.project.web.MyWebService" />
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json" />
        </jaxrs:extensionMappings>
    </jaxrs:server>
</beans>

我的服务处于活动状态 (http://localhost:8080/{warname}/myws/doSomething),但 MyCore 实例未注入 MyWebService(在 myCore 字段中)。它始终为 null,我的服务无法按预期工作,而是抛出 NullPointerException

尝试了通过 google 收集的所有输入。没有运气!非常感谢您的帮助。

问候

【问题讨论】:

    标签: spring cxf jboss6.x


    【解决方案1】:

    尝试将以下方法添加到您的网络服务:

    @PostConstruct
    public void init() {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    }
    

    当前 Web 应用程序上下文(通常是由 ContextLoaderListener 加载的上下文)将用于自动装配,因此 IMyCore bean 必须在上下文侦听器配置文件中定义,而不是在 Web 服务中定义。

    【讨论】:

    • 现在该项目已经发生了一些变化,以尝试您建议的解决方案。但我肯定会在代码库的本地副本上尝试它,并借给你知道。感谢发帖!
    【解决方案2】:

    如果你想在 CXF Web Service 类中使用 Spring Beans,那么在 CXF 的 XML 配置文件中声明 WebService 如下(例如 spring-cxf.xml)

    <bean id="hello" class="demo.spring.service.HelloWorldImpl" />
    <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />
    

    为 WebService 类声明分离的 bean,然后将其放入带有 ID 的端点中。像这样,您将拥有 spring 托管 bean,您也可以在其中使用 AutoWired 注释。

    如果您将 Web 服务声明如下,您的 bean 将永远不会被自动注入。

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    <jaxws:endpoint id="helloWorld" implementor="demo.spring.service.HelloWorldImpl" address="/HelloWorld"/>
    

    在这种情况下,您将需要:

    • 手动注入spring bean

      SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

    • 或者从 spring 上下文中一一取回 bean

      ApplicationContext context = ...; // your Spring ApplicationContext HelloBean helloBean = (HelloBean) context.getBean("bean");

      我没有为 JAX-RS 尝试过这个,但我认为方法应该是相同的。

      From CXF official documentation.

    【讨论】:

      【解决方案3】:

      尝试在 Beans.xml 中添加下面的 bean 配置

      <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
      

      就我而言,它有效..

      【讨论】:

      • 我试过了,但它对我不起作用。似乎 Web 服务不是由 Spring 创建的,因此没有自动装配。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多