2012-06-04 6 views
5

tôi dường như chạy vào một vấn đề nhỏ khi sử dụng @Autowired thành một bộ chặn đánh chặn cxf tùy chỉnh. Trường hợp sử dụng của tôi là tôi muốn ghi lại các tin nhắn xà phòng và gửi chúng bằng AMQP tới một hệ thống khác. Quá trình này hoạt động cho các dịch vụ thông thường, vv .. Nhưng bất cứ điều gì tôi làm, các thuộc tính cần thiết không nhận được autowired và ở lại null.Làm thế nào để sử dụng Spring Autowired trong bộ chặn đánh dấu cxf tùy chỉnh?

Tôi đã kiểm tra nhật ký Spring DI và bối cảnh được quét và chọn, vì vậy tôi đang thiếu gì?

Điều này có thể thực hiện được trong các thiết bị đánh chặn CXF không?

@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()); 
    } 

} 
+0

Bằng cách "nhặt" bạn có nghĩa là LogInInterceptor của bạn đang được tìm thấy và có đủ điều kiện tiêm từ thùng chứa mùa xuân? Nó đã báo cáo bất kỳ vấn đề nào khác với việc tiêm (chẳng hạn như thất bại tại tham số @Value)? –

+0

Bạn có thể chia sẻ cấu hình cho thiết bị chặn này với CXF không. Lý do cho vấn đề này có thể là máy đánh chặn có thể đã được khởi tạo bởi CXF và một cá thể tự động riêng biệt có thể đã được tạo ra bởi Spring. –

+0

Tôi đã triển khai trình chặn như ở trên và thêm nó vào dịch vụ web của tôi qua @ org.apache.cxf.interceptor.InInterceptors (interceptors = {"org.apache.cxf.interceptor.LoggingInInterceptor", "mypackagenames.ws.interceptor.LogInInterceptor "}) Tôi hoàn toàn không thực hiện cấu hình bổ sung nào. – Marco

Trả lời

7

Bạn không thể trộn lẫn @InInterceptors (một chú thích CXF) @Component (một chú thích mùa xuân). Điều đó sẽ tạo ra hai trường hợp riêng biệt của interceptor của bạn: một trong những phụ thuộc của nó đang được tiêm bởi Spring, và một trong những được tạo ra bởi CXF. (Bạn đang cung cấp tên lớp trong @InInterceptors chú thích, không phải là một ID đậu, vì vậy CXF không có cách nào để biết rằng bạn đã tạo ra một thể hiện trong bối cảnh mùa xuân.)

Tháo @InInterceptors chú thích và, ngoài các component scan :

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

bạn cũng cần một cái gì đó như thế này trong bối cảnh ứng dụng của bạn:

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

Quét thành phần thành công, tên gói chính xác nằm trong tệp xml mùa xuân. Tuy nhiên các thuộc tính không được tiêm .. Bất kỳ đầu mối khác? – Marco

+0

Có. Tôi đã chỉnh sửa câu trả lời của tôi dựa trên phản hồi của bạn với Biju. –

+0

Hoạt động của nó! Cảm ơn bạn đã giải thích rõ ràng và giúp thực hiện điều này. – Marco

1

tôi biết đây là một câu hỏi cũ, nhưng Jonathan W của câu trả lời giúp tôi và tôi muốn thêm cho nó.

Đây là cách tôi đã chặn tùy chỉnh và @Autowired để làm việc với mùa xuân 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 
    } 

}