2012-06-04 29 views
5

me parece que tengo un pequeño problema cuando uso @Autowired en un interceptor cxf personalizado. Mi caso de uso es que quiero registrar mensajes de jabón y enviarlos usando AMQP a otro sistema. Este proceso funciona para servicios normales, etc. Pero haga lo que haga, las propiedades necesarias no se autoconectan y permanecen nulas.Cómo usar Spring Autowired en un interceptor cxf personalizado?

he comprobado el registro DI primavera y el contexto se escanea y se pickedup, así que lo que me falta?

Es esto posible en interceptores 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

Por "recogido" quiere decir que su LogInInterceptor está siendo encontrado y es elegible para inyección desde el contenedor de primavera? ¿Ha reportado algún otro problema con la inyección (como fallar en el parámetro @Value)? –

+0

¿Puede compartir la configuración de este interceptor con CXF también? La razón de este problema puede ser que el interceptor puede haber creado una instancia de CXF y una instancia separada autowired puede haber sido creado por la primavera. –

+0

He implementado el interceptor como antes y se añadió a mi servicio web a través de los org.apache.cxf.interceptor.InInterceptors @ (interceptores = { "mypackagenames.ws.interceptor.LogInInterceptor "org.apache.cxf.interceptor.LoggingInInterceptor" "}) No realicé ninguna configuración adicional. – Marco

Respuesta

7

No se puede mezclar @InInterceptors (una anotación de CXF) y @Component (una anotación de primavera). Eso creará dos instancias separadas de su interceptor: el que las dependencias están siendo inyectadas por Spring y el otro creado por CXF. (Usted está proporcionando los nombres de clase en el @InInterceptors anotación, no es un ID de frijol, por lo CXF no tiene manera de saber que ya ha creado una instancia en el contexto de Primavera.)

Retire la anotación @InInterceptors y, además de la component scan :

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

también necesita algo como esto en su contexto de aplicación:

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

El escaneo de componentes tiene éxito, el nombre correcto del paquete está en el archivo xml de primavera. Aún así, las propiedades no se inyectan. ¿Alguna otra pista? – Marco

+0

Sí. Edité mi respuesta en función de sus comentarios a Biju. –

+0

¡Está funcionando! Gracias por la clara explicación y ayuda para implementar esto. – Marco

1

sé que esto es una vieja pregunta, pero la respuesta de Jonathan W me ayudó y me gustaría añadir a eso.

Esto es cómo llegué interceptores personalizados y @Autowired a trabajar con la primavera de arranque 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 
    } 

} 
Cuestiones relacionadas