복붙노트

[SPRING] 커스텀 cxf 인터셉터에서 Spring Autowired를 사용하는 방법?

SPRING

커스텀 cxf 인터셉터에서 Spring Autowired를 사용하는 방법?

@Autowired를 사용자 지정 cxf 인터셉터로 사용할 때 작은 문제가있는 것 같습니다. 내 유스 케이스는 비누 메시지를 기록하고 AMQP를 사용하여 다른 시스템에 보내려고한다는 것입니다. 이 프로세스는 정상적인 서비스 등에서 작동합니다. 그러나 내가 무엇을 하든지, 필요한 속성은 자동으로 실행되지 않고 null이 아닙니다.

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

}

해결법

  1. ==============================

    1.@InInterceptors (CXF annotation)와 @Component (Spring annotation)을 혼합 할 수는 없습니다. 그러면 인터셉터의 두 인스턴스가 생성됩니다. 인터셉터의 인스턴스는 Spring에 의해 의존성이 주입되는 인스턴스와 CXF에 의해 생성 된 인스턴스입니다. (Bean ID가 아닌 @InInterceptors 어노테이션에 클래스 이름을 제공하므로 CXF는 Spring 컨텍스트에서 이미 인스턴스를 작성했는지 알 수 없다.)

    @InInterceptors (CXF annotation)와 @Component (Spring annotation)을 혼합 할 수는 없습니다. 그러면 인터셉터의 두 인스턴스가 생성됩니다. 인터셉터의 인스턴스는 Spring에 의해 의존성이 주입되는 인스턴스와 CXF에 의해 생성 된 인스턴스입니다. (Bean ID가 아닌 @InInterceptors 어노테이션에 클래스 이름을 제공하므로 CXF는 Spring 컨텍스트에서 이미 인스턴스를 작성했는지 알 수 없다.)

    @InInterceptors 주석을 제거하고 구성 요소 검사 외에 다음을 수행하십시오.

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

    또한 응용 프로그램 컨텍스트에서 다음과 같은 것이 필요합니다.

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

    2.나는 이것이 오래된 질문 인 것을 안다. 그러나 Jonathan W의 대답은 나를 도왔다. 나는 그것에 덧붙이고 싶다.

    나는 이것이 오래된 질문 인 것을 안다. 그러나 Jonathan W의 대답은 나를 도왔다. 나는 그것에 덧붙이고 싶다.

    이것이 스프링 부트 1.3.1에서 작동하도록 사용자 정의 인터셉터와 @Autowired를 얻은 방법입니다.

    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
        }
    
    }
    
  3. from https://stackoverflow.com/questions/10888501/how-to-use-spring-autowired-in-a-custom-cxf-interceptor by cc-by-sa and MIT license