[SPRING] 스프링 부트 JAX-WS 웹 서비스를 bean으로 등록
SPRING스프링 부트 JAX-WS 웹 서비스를 bean으로 등록
내 봄 부팅 ws 기반 응용 프로그램에서 나는 jax-ws webservice 계약 첫 번째 접근법을 만들었습니다. 웹 서비스가 작동하지만 웹 서비스 내 다른 콩을 autowire 수 없습니다.
어떻게 스프링으로 웹 서비스를 bean으로 정의 할 수 있습니까?
다음은 내 webservice impl 클래스입니다.
@WebService(endpointInterface = "com.foo.bar.MyServicePortType")
@Service
public class MySoapService implements MyServicePortType {
@Autowired
private MyBean obj;
public Res method(final Req request) {
System.out.println("\n\n\nCALLING.......\n\n" + obj.toString()); //obj is null here
return new Res();
}
}
내 서비스 포트 유형이 wsdl 파일의 maven에 의해 생성됩니다.
SoapUi를 통해이 서비스를 호출하면 MyBean 객체가 자동 실행되지 않으므로 NullPointerException이 발생합니다.
내 응용 프로그램은 스프링 부팅을 기반으로하므로 xml 파일은 없습니다. 현재 엔드 포인트 구성을 가진 sun-jaxws.xml 파일이 있습니다. 스프링 부트 응용 프로그램에서 다음 구성을 수행하려면 어떻게해야합니까?
<wss:binding url="/hello">
<wss:service>
<ws:service bean="#helloWs"/>
</wss:service>
</wss:binding>
다음은 SpringBootServletInitializer 클래스입니다.
@Configuration
public class WebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(WSApplication.class);
}
@Bean
public ServletRegistrationBean jaxws() {
final ServletRegistrationBean jaxws = new ServletRegistrationBean(new WSServlet(), "/jaxws");
return jaxws;
}
@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new WSServletContextListener());
}
}
감사
해결법
-
==============================
1.SpringBeanAutowiringSupport를 확장하는 것은 JAX-WS 엔드 포인트 클래스에 삽입 된 콩을 현재의 스프링 루트 웹 애플리케이션 컨텍스트에서 가져 오는 데 권장되는 방법이다. 그러나 이것은 서블릿 컨텍스트 초기화에서 약간 다르기 때문에 스프링 부트에서는 작동하지 않습니다.
SpringBeanAutowiringSupport를 확장하는 것은 JAX-WS 엔드 포인트 클래스에 삽입 된 콩을 현재의 스프링 루트 웹 애플리케이션 컨텍스트에서 가져 오는 데 권장되는 방법이다. 그러나 이것은 서블릿 컨텍스트 초기화에서 약간 다르기 때문에 스프링 부트에서는 작동하지 않습니다.
SpringBootServletInitializer.startup ()은 사용자 정의 ContextLoaderListener를 사용하며 작성된 응용 프로그램 컨텍스트를 ContextLoader에 전달하지 않습니다. 나중에 JAX-WS 엔드 포인트 클래스의 객체가 초기화 될 때 SpringBeanAutowiringSupport는 ContextLoader에 의존하여 현재 애플리케이션 컨텍스트를 검색하고 항상 null을 가져온다.
public abstract class SpringBootServletInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { WebApplicationContext rootAppContext = createRootApplicationContext( servletContext); if (rootAppContext != null) { servletContext.addListener(new ContextLoaderListener(rootAppContext) { @Override public void contextInitialized(ServletContextEvent event) { // no-op because the application context is already initialized } }); } ...... } }
org.springframework.boot.context.embedded.ServletContextInitializer를 구현 한 bean을 등록하여 startup () 중에 애플리케이션 컨텍스트를 검색 할 수있다.
@Configuration public class WebApplicationContextLocator implements ServletContextInitializer { private static WebApplicationContext webApplicationContext; public static WebApplicationContext getCurrentWebApplicationContext() { return webApplicationContext; } @Override public void onStartup(ServletContext servletContext) throws ServletException { webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); } }
그런 다음 JAX-WS 엔드 포인트 클래스에 자체 자동 와이어 링을 구현할 수 있습니다.
@WebService public class ServiceImpl implements ServicePortType { @Autowired private FooBean bean; public ServiceImpl() { AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); WebApplicationContext currentContext = WebApplicationContextLocator.getCurrentWebApplicationContext(); bpp.setBeanFactory(currentContext.getAutowireCapableBeanFactory()); bpp.processInjection(this); } // alternative constructor to facilitate unit testing. protected ServiceImpl(ApplicationContext context) { AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); bpp.setBeanFactory(new DefaultListableBeanFactory(context)); bpp.processInjection(this); } }
유닛 테스트에서 현재 스프링 애플리케이션 컨텍스트를 주입하고 대체 생성자를 호출 할 수 있습니다.
@Autowired private ApplicationContext context; private ServicePortType service; @Before public void setup() { this.service = new ServiceImpl(this.context); }
-
==============================
2.SpringBootServletInitializer에서 Configuration을 확장하거나 configure () 또는 onStartup () 메소드를 재정의하지 않아도됩니다. 그리고 WebApplicationInitializer를 구현하는 무언가를 만들어야합니다. 몇 단계 만 수행하면됩니다 (@Configuration 클래스의 모든 단계를 수행 할 수도 있습니다. @SpringBootApplication 클래스는 @ComponentScan 등을 통해 알 수 있습니다).
SpringBootServletInitializer에서 Configuration을 확장하거나 configure () 또는 onStartup () 메소드를 재정의하지 않아도됩니다. 그리고 WebApplicationInitializer를 구현하는 무언가를 만들어야합니다. 몇 단계 만 수행하면됩니다 (@Configuration 클래스의 모든 단계를 수행 할 수도 있습니다. @SpringBootApplication 클래스는 @ComponentScan 등을 통해 알 수 있습니다).
끝난.
@SpringBootApplication public class SimpleBootCxfApplication { public static void main(String[] args) { SpringApplication.run(SimpleBootCxfApplication.class, args); } @Bean public ServletRegistrationBean dispatcherServlet() { return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*"); } @Bean(name = Bus.DEFAULT_BUS_ID) public SpringBus springBus() { return new SpringBus(); } @Bean public WeatherService weatherService() { return new WeatherServiceEndpoint(); } @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), weatherService()); endpoint.publish("/WeatherSoapService"); return endpoint; } }
-
==============================
3.기본적으로 Spring은 JAX-WS 엔드 포인트에 대해 아무것도 모릅니다. Spring이 아닌 JAX-WS 런타임에 의해 관리됩니다. SpringBeanAutowiringSupport를 사용하면이 문제를 극복 할 수 있습니다. 일반적으로 하위 클래스로 간단히 처리 할 수 있습니다.
기본적으로 Spring은 JAX-WS 엔드 포인트에 대해 아무것도 모릅니다. Spring이 아닌 JAX-WS 런타임에 의해 관리됩니다. SpringBeanAutowiringSupport를 사용하면이 문제를 극복 할 수 있습니다. 일반적으로 하위 클래스로 간단히 처리 할 수 있습니다.
public class MySoapService extends SpringBeanAutowiringSupport implements MyServicePortType { … }
@PostConstruct로 주석 된 메소드에서 직접 호출 할 수도 있습니다.
public class MySoapService implements MyServicePortType { @PostConstruct public void init() { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); } }
-
==============================
4.SpringBeanAutoWiringSupport를 사용하여 @Andy Wilkinson의 단서를 얻는 것은
SpringBeanAutoWiringSupport를 사용하여 @Andy Wilkinson의 단서를 얻는 것은
public class MySoapService extends SpringBeanAutowiringSupport implements MyServicePortType { … }
@PostConstruct로 주석 된 메소드에서 직접 호출 할 수도 있습니다.
@Service public class MySoapService implements MyServicePortType { @Autowired ServletContext servletContext; @PostConstruct public void init() { SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletContext); } }
from https://stackoverflow.com/questions/25177491/spring-boot-register-jax-ws-webservice-as-bean by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring을 사용하는 CXF에서 다중 resouceBean 구성 (0) | 2019.04.01 |
---|---|
[SPRING] 그것은 나를 500 던졌습니다 봄 보안에 표현 'ROLE_USER'을 평가하지 못했습니다 (0) | 2019.04.01 |
[SPRING] Spring - No WebApplicationContext found : ContextLoaderListener가 등록되지 않았습니까? [복제] (0) | 2019.04.01 |
[SPRING] spring-test-mvc 프레임 워크로 Spring REST 컨트롤러 테스트 (0) | 2019.04.01 |
[SPRING] AnnotationConfigApplicationContext 및 부모 컨텍스트 (0) | 2019.04.01 |