【问题标题】:How to use Spring Autowired in a custom cxf interceptor?如何在自定义 cxf 拦截器中使用 Spring Autowired?
【发布时间】:2012-06-04 21:17:08
【问题描述】:

在自定义 cxf 拦截器中使用 @Autowired 时,我似乎遇到了一个小问题。 我的用例是我想记录肥皂消息并使用 AMQP 将这些消息发送到另一个系统。此过程适用于正常服务等。 但无论我做什么,所需的属性都不会自动装配并保持为空。

我检查了 Spring DI 日志并扫描并提取了上下文,那么我缺少什么?

这在 CXF 拦截器中是否可行?

@Component
public class LogInInterceptor extends AbstractSoapInterceptor {

    private @Value("#{rabbitMQProperties['rabbitmq.binding.log.soap']}")
    String binding;

    @Autowired
    AmqpTemplate amqpTemplate;

    public LogInInterceptor() {
        super(Phase.RECEIVE);
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        logIt(soapMessage);
    }

    private void logIt(SoapMessage message) throws Fault {
        // rest of the code omitted...!!!     
        amqpTemplate.convertAndSend(binding, buffer.toString());
    }

}

【问题讨论】:

  • 通过“拾取”你的意思是你的 LogInInterceptor 被找到并且有资格从 Spring 容器注入?它是否报告了注入的任何其他问题(例如 @Value 参数失败)?
  • 你能把这个拦截器的配置也分享给CXF吗?出现此问题的原因可能是拦截器可能已被 CXF 实例化,并且可能已由 Spring 创建单独的自动装配实例。
  • 我已经实现了上面的拦截器,并通过@org.apache.cxf.interceptor.InInterceptors (interceptors = {"org.apache.cxf.interceptor.LoggingInInterceptor"," mypackagenames.ws.interceptor.LogInInterceptor"}) 我根本没有执行任何额外的配置。
  • 马尔科,这就是原因。 CXF 正在创建对象并使用该对象,而不是 Spring。

标签: web-services spring dependency-injection cxf


【解决方案1】:

您不能混合使用@InInterceptors(CXF 注释)@Component(Spring 注释)。这将创建两个独立的拦截器实例:一个其依赖项由 Spring 注入,另一个由 CXF 创建。 (您在 @InInterceptors 注释中提供类名,而不是 bean ID,因此 CXF 无法知道您已经在 Spring 上下文中创建了一个实例。)

删除@InInterceptors 注释,除了component scan

<context:component-scan base-package="org.example.config"/>

您的应用程序上下文中还需要这样的东西:

<jaxws:endpoint id="myWebService" address="/MyWebService">
    <jaxws:inInterceptors>
        <ref bean="myInInterceptor" />
    </jaxws:inInterceptors>
</jaxws:endpoint>

【讨论】:

  • 组件扫描成功,正确的包名在spring xml文件中。仍然没有注入属性..还有其他线索吗?
  • 它的工作!感谢您的明确解释并帮助实现这一点。
【解决方案2】:

我知道这是一个老问题,但乔纳森 W 的回答对我有帮助,我想补充一下。

这就是我如何让自定义拦截器和 @Autowired 与 Spring Boot 1.3.1 一起使用:

http://cxf.apache.org/docs/jax-ws-configuration.html

import java.util.Arrays;

import javax.jws.WebService;

import org.apache.cxf.Bus;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@EnableAutoConfiguration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class Application extends SpringBootServletInitializer {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private MyInterceptor myInterceptor;

    @Autowired
    private HelloWorldImpl helloWorldImpl;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    // Replaces the need for web.xml
    @Bean
    public ServletRegistrationBean servletRegistrationBean(ApplicationContext context) {
        return new ServletRegistrationBean(new CXFServlet(), "/api/*");
    }

    // Replaces cxf-servlet.xml
    @Bean
    // <jaxws:endpoint id="helloWorld" implementor="demo.spring.service.HelloWorldImpl" address="/HelloWorld"/>
    public EndpointImpl helloService() {
        Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID);
        EndpointImpl endpoint = new EndpointImpl(bus, helloWorldImpl);

        // Set interceptors here
        endpoint.setInInterceptors(Arrays.asList(myInterceptor));

        endpoint.publish("/hello");
        return endpoint;
    }


    // Used when deploying to a standalone servlet container, i.e. tomcat
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    // Web service endpoint
    @WebService(endpointInterface = "demo.spring.service.HelloWorld")
    //@InInterceptors not defined here
    public static class HelloWorldImpl {

    }

    public static class MyInterceptor extends LoggingInInterceptor {
      // @Autowired works here
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 2017-08-02
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多