I created my own autoconfiguration to auto-register services to CXF:
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class ServiceConfig {
@Inject
private ApplicationContext applicationContext;
@Inject
private ObjectMapperFactory objectMapperFactory;
@Bean
public ServletRegistrationBean cxfServletRegistration() {
return new ServletRegistrationBean(new CXFServlet(), "/services/*");
}
@Bean
public JacksonJsonProvider jacksonJsonProvider() {
return new JacksonJsonProvider(this.objectMapperFactory.createInstance());
}
@Bean
public Server jaxRsServer() {
List<Object> restServiceBeans = new ArrayList<>(this.applicationContext.getBeansWithAnnotation(Path.class).values());
List<Object> providerBeans = new ArrayList<>(
this.applicationContext.getBeansWithAnnotation(Provider.class).values());
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setBus(this.applicationContext.getBean(SpringBus.class));
factory.setAddress("/rest");
factory.setServiceBeans(restServiceBeans);
factory.setProviders(providerBeans);
return factory.create();
}
}
Next I added this as META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.oasp.module.rest.ServiceConfig
Works like a charm if there are services available...
However my spring tests in the same module stopped working.
I am using a dummy @SpringBootApplication class to configure the tests. Now I can see that ServiceConfig.jaxRsServer() is called in the test what lets the application context fail to startup.
I added an exclude on ServiceConfig but still I am getting the same error.
@SpringBootApplication(exclude = { ServiceConfig.class })
public class SpringBootTestConfig {
I also observed the same problem for regular spring boot apps (without spring-test). It seems as if @SpringBootApplication.exclude is ignored in my context. Spring will still instantiate the excluded ServiceConfig and call all @Bean methods what fails in that case. All I want is to tell spring to stop instantiating my ServiceConfig and IMHO that is exactly what @SpringBootApplication.exclude should be for.
In case I am using @Profile I can prevent spring from instantiating the ServiceConfig but this is not a real solution.
Comment From: philwebb
Is your ServiceConfig class in sub-package of SpringBootTestConfig? If so it might be getting loaded due to @ComponentScan. Perhaps try replacing @SpringBootApplication with @Configuration and @EnableAutoConfiguration (and leave off @ComponentScan)
Comment From: hohwille
Is your ServiceConfig class in sub-package of SpringBootTestConfig?
Jep. Thanks for the explanation. You saved my day.
I added this to SpringBootTestConfig and now it is working:
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceConfig.class) )
For users not understanding the internals of spring the behavior of "exclude" is somewhat confusing. However, feel free to close this issue as there is a easy workaround.
Comment From: muzhix
thank guys, it's working