SpringBeanAutowiringSupport推荐使用扩展方法,从当前的Spring根Web应用程序上下文中为JAX-
WS端点类注入bean。但是,这不适用于 spring boot,
因为它在servlet上下文初始化方面有些不同。
问题
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()。
@Configurationpublic 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端点类中实现自动装配。
@WebServicepublic 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); }}单元测试
在单元测试中,您可以注入当前的spring应用程序上下文,并使用它调用替代构造函数。
@Autowired private ApplicationContext context;private ServicePortType service;@Beforepublic void setup() { this.service = new ServiceImpl(this.context);}


