Автообнаружение ресурсов JAX-RS с помощью CXF в приложении Spring


Можно ли с помощью Apache CXF (2.7.0) автоматически обнаружить ресурсы JAX-RS в пути к классу ? То есть классы с аннотациями @Path.

Я использую CXF в приложении Spring, и мне приходится вручную объявлять ресурсы со следующим XML, даже если ресурсы успешно обнаружены Spring <context:component-scan ...>.

<jaxrs:server id="myService" address="/myService">
    <jaxrs:serviceBeans>
        <ref bean="myResource1" />
        <ref bean="myResource2" />
        <ref bean="myResource3" />
    </jaxrs:serviceBeans>
</jaxrs:server>

Я хотел бы избежать этого (как я могу сделать с другими реализациями JAX-RS, такими как resteasy), потому что в моем случае это сложнее поддерживать, и это заставляет меня объявлять мои бобовые зависимости в файле конфигурации Spring XML.

4 11

4 ответа:

Похоже, что в настоящее время в CXF 2.7 нет способа сделать это с помощью конфигурации Spring. Если вы посмотрите на resteasy, они реализовали BeanFactoryPostProcessor SpringBeanProcessor.java, которая ищет @Path и @Provider. Что-то подобное, вероятно, можно было бы сделать в CXF, но это пока не реализовано. Похоже, вы не единственный, кто заинтересован CXF-3725

Этот код делает трюк:

@Configuration
@ComponentScan
@ImportResource({"classpath:META-INF/cxf/cxf.xml"})
public class Context {
    @Autowired
    private ApplicationContext ctx;

    @Bean
    public Server jaxRsServer() {
        LinkedList<ResourceProvider> resourceProviders = new LinkedList<>();
        for (String beanName : ctx.getBeanDefinitionNames()) {
            if (ctx.findAnnotationOnBean(beanName, Path.class) != null) {
                SpringResourceFactory factory = new SpringResourceFactory(beanName);
                factory.setApplicationContext(ctx);
                resourceProviders.add(factory);
            }
        }

        JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
        factory.setBus(ctx.getBean(SpringBus.class));
        factory.setProviders(Arrays.asList(new JacksonJsonProvider()));
        factory.setResourceProviders(resourceProviders);
        return factory.create();
    }
}

Просто не забудьте поместить CXFServlet в вашу сеть.xml-и все готово.

Протестировано и работает в cxf 3.0.4.

<jaxrs:server address="/" basePackages="a.b.c"/>

Не забудьте упомянуть CXF-сервлет в web.xml

В дополнение к тому, что было предложено: это действительно работает в 3.0.0-milestone2, можно было бы просто сделать объявление сервера jaxrs верхнего уровня только и установить атрибут basePackages, который может иметь одно или несколько имен пакетов, разделенных пробелом.