2012-06-04 13 views
5

Mi sembra di imbattersi in un piccolo problema quando si utilizza @Autowired in un intercettore personalizzato cxf. Il mio caso d'uso è che voglio registrare i messaggi soap e inviarli usando AMQP su un altro sistema. Questo processo funziona per servizi normali, ecc. Ma qualunque cosa faccia, le proprietà necessarie non vengono autorizzate e rimangono nulle.Come utilizzare Spring Autowired in un intercettore cxf personalizzato?

Ho controllato il registro DI priming e il contesto è scansionato e prelevato, quindi cosa mi manca?

Ciò è possibile anche negli intercettori 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()); 
    } 

} 
+0

Con "raccolto" vuoi dire che il vostro LogInInterceptor è stato trovato ed è ammissibile per iniezione dal contenitore Spring? Ha segnalato altri problemi con l'iniezione (come il fallimento del parametro @Value)? –

+0

Potete condividere anche la configurazione per questo intercettore con CXF. La ragione di questo problema potrebbe essere che l'intercettore potrebbe essere stato istanziato da CXF e un'istanza autowired separata potrebbe essere stata creata da Spring. –

+0

Ho implementato l'intercettore come sopra e l'ho aggiunto al mio webservice tramite @ org.apache.cxf.interceptor.InInterceptors (interceptors = {"org.apache.cxf.interceptor.LoggingInInceptceptor", "mypackagenames.ws.interceptor.LogInInceptceptor "}) Non ho eseguito alcuna configurazione aggiuntiva. – Marco

risposta

7

Non è possibile combinare @InInterceptors (un'annotazione CXF) e@Component (un'annotazione primavera). Ciò creerà due istanze separate del tuo intercettore: quella le cui dipendenze vengono iniettate da Spring e una creata da CXF. (Si sta fornendo i nomi di classe nel @InInterceptors annotazione, non un ID di fagioli, in modo da CXF non ha alcun modo di sapere che è già stato creato un caso nel contesto primavera.)

Rimuovere il @InInterceptors annotazione e, in aggiunta al component scan :

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

è inoltre necessario qualcosa di simile nel vostro contesto di applicazione:

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

La scansione del componente ha esito positivo, il nome del pacchetto corretto si trova nel file xml di primavera. Ancora le proprietà non vengono iniettate .. Qualche altro indizio? – Marco

+0

Sì. Ho modificato la mia risposta sulla base del tuo feedback a Biju. –

+0

Funziona! Grazie per la chiara spiegazione e aiuto per l'implementazione di questo. – Marco

1

so che questa è una vecchia questione, ma la risposta di Jonathan W mi ha aiutato e mi piacerebbe aggiungere ad esso.

Questo è come mi sono intercettori personalizzati e @Autowired a lavorare con la Primavera 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 
    } 

} 
Problemi correlati