You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2016/07/11 00:14:16 UTC

[11/33] cxf git commit: [CXF-5091] Improving the client side Spring support

[CXF-5091] Improving the client side Spring support


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a2d869b5
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a2d869b5
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a2d869b5

Branch: refs/heads/master-jaxrs-2.1
Commit: a2d869b515f99d1361484d34895325d8c4c2047c
Parents: 46040f8
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Wed Jul 6 17:06:57 2016 +0100
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Wed Jul 6 17:06:57 2016 +0100

----------------------------------------------------------------------
 .../rs/service/SampleRestApplication.java       | 28 +++++++++
 .../src/main/resources/application.properties   |  4 +-
 .../spring/AbstractJaxrsClassesScanServer.java  | 22 ++-----
 .../JAXRSServerFactoryBeanDefinitionParser.java | 39 ++++++------
 .../AbstractJaxRsClientConfiguration.java       | 57 +++++++++++++++++
 .../client/spring/EnableJaxRsProxyClient.java   | 33 ++++++++++
 .../client/spring/EnableJaxRsWebClient.java     | 33 ++++++++++
 .../JAXRSClientFactoryBeanDefinitionParser.java | 24 ++++++++
 .../JaxRsClientClassesScanConfiguration.java    | 60 ++++++++++++++++++
 .../client/spring/WebClientConfiguration.java   | 64 ++++++++++++++++++++
 10 files changed, 327 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/java/sample/rs/service/SampleRestApplication.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/java/sample/rs/service/SampleRestApplication.java b/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/java/sample/rs/service/SampleRestApplication.java
index f739e95..8839c1b 100644
--- a/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/java/sample/rs/service/SampleRestApplication.java
+++ b/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/java/sample/rs/service/SampleRestApplication.java
@@ -22,8 +22,12 @@ import java.util.Arrays;
 import org.apache.cxf.Bus;
 import org.apache.cxf.endpoint.Server;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.client.spring.EnableJaxRsProxyClient;
+import org.apache.cxf.jaxrs.client.spring.EnableJaxRsWebClient;
 import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
@@ -32,6 +36,8 @@ import sample.rs.service.hello1.HelloServiceImpl1;
 import sample.rs.service.hello2.HelloServiceImpl2;
 
 @SpringBootApplication
+@EnableJaxRsWebClient
+@EnableJaxRsProxyClient
 public class SampleRestApplication {
     @Autowired
     private Bus bus;
@@ -50,4 +56,26 @@ public class SampleRestApplication {
         return endpoint.create();
     }
  
+    @Bean
+    CommandLineRunner initWebClientRunner(final WebClient webClient) {
+      
+      return new CommandLineRunner() {
+
+        @Override
+        public void run(String... runArgs) throws Exception {
+            System.out.println(webClient.accept("text/plain").path("sayHello/ApacheCxfWebClientUser").get(String.class));
+        }
+      };
+    }
+    @Bean
+    CommandLineRunner initProxyClientRunner(final HelloService client) {
+      
+      return new CommandLineRunner() {
+
+        @Override
+        public void run(String... runArgs) throws Exception {
+            System.out.println(client.sayHello("ApacheCxfProxyUser"));
+        }
+      };
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/resources/application.properties b/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/resources/application.properties
index 27c5c26..955d403 100644
--- a/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/resources/application.properties
+++ b/distribution/src/main/release/samples/jax_rs/spring_boot/src/main/resources/application.properties
@@ -1 +1,3 @@
-cxf.path=/services/helloservice
\ No newline at end of file
+cxf.path=/services/helloservice
+cxf.jaxrs.client.address=http://localhost:8080/services/helloservice
+cxf.jaxrs.client.classes-scan-packages=sample.rs.service

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractJaxrsClassesScanServer.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractJaxrsClassesScanServer.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractJaxrsClassesScanServer.java
index bfe7625..e1bfa13 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractJaxrsClassesScanServer.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/AbstractJaxrsClassesScanServer.java
@@ -19,7 +19,6 @@
 package org.apache.cxf.jaxrs.spring;
 
 import java.lang.annotation.Annotation;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -31,7 +30,6 @@ import org.apache.cxf.common.util.ClasspathScanner;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
 import org.apache.cxf.service.factory.ServiceConstructionException;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 public abstract class AbstractJaxrsClassesScanServer extends AbstractSpringConfigurationFactory {
     @Value("${cxf.jaxrs.classes-scan-packages}")
     private String basePackages;
@@ -44,8 +42,10 @@ public abstract class AbstractJaxrsClassesScanServer extends AbstractSpringConfi
             final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes =
                 ClasspathScanner.findClasses(basePackages, Provider.class, Path.class);
                                       
-            List<Object> jaxrsServices = createBeansFromDiscoveredClasses(classes.get(Path.class));
-            List<Object> jaxrsProviders = createBeansFromDiscoveredClasses(classes.get(Provider.class));
+            List<Object> jaxrsServices = JAXRSServerFactoryBeanDefinitionParser
+                .createBeansFromDiscoveredClasses(super.applicationContext, classes.get(Path.class), null); 
+            List<Object> jaxrsProviders = JAXRSServerFactoryBeanDefinitionParser
+                .createBeansFromDiscoveredClasses(super.applicationContext, classes.get(Provider.class), null);
             
             factory.setServiceBeans(jaxrsServices);
             factory.setProviders(jaxrsProviders);
@@ -55,18 +55,4 @@ public abstract class AbstractJaxrsClassesScanServer extends AbstractSpringConfi
         
     }
         
-    protected List<Object> createBeansFromDiscoveredClasses(Collection<Class<?>> classes) {
-        AutowireCapableBeanFactory beanFactory = super.applicationContext.getAutowireCapableBeanFactory();
-        final List< Object > providers = new ArrayList< Object >();
-        for (final Class< ? > clazz: classes) {
-            Object bean = null;
-            try {
-                bean = beanFactory.createBean(clazz, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
-            } catch (Exception ex) {
-                bean = beanFactory.createBean(clazz);
-            }
-            providers.add(bean);
-        }
-        return providers;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
index ce7efea..d10bd66 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
@@ -222,9 +222,11 @@ public class JAXRSServerFactoryBeanDefinitionParser extends AbstractBeanDefiniti
                     final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes =
                         ClasspathScanner.findClasses(basePackages, Provider.class, Path.class);
                                               
-                    this.setServiceBeans(createBeansFromDiscoveredClasses(classes.get(Path.class),
+                    this.setServiceBeans(createBeansFromDiscoveredClasses(context,
+                                                                          classes.get(Path.class),
                                                                           serviceAnnotationClass));
-                    this.setProviders(createBeansFromDiscoveredClasses(classes.get(Provider.class),
+                    this.setProviders(createBeansFromDiscoveredClasses(context,
+                                                                       classes.get(Provider.class),
                                                                        serviceAnnotationClass));
                 } catch (IOException ex) {
                     throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
@@ -256,23 +258,24 @@ public class JAXRSServerFactoryBeanDefinitionParser extends AbstractBeanDefiniti
             } 
             return null;
         }
-        private List<Object> createBeansFromDiscoveredClasses(Collection<Class<?>> classes, 
-                                                              Class<? extends Annotation> serviceClassAnnotation) {
-            AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
-            final List< Object > providers = new ArrayList< Object >();
-            for (final Class< ? > clazz: classes) {
-                if (serviceClassAnnotation != null && clazz.getAnnotation(serviceClassAnnotation) == null) {
-                    continue;
-                }
-                Object bean = null;
-                try {
-                    bean = beanFactory.createBean(clazz, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
-                } catch (Exception ex) {
-                    bean = beanFactory.createBean(clazz);
-                }
-                providers.add(bean);
+    }
+    static List<Object> createBeansFromDiscoveredClasses(ApplicationContext context,
+                                                         Collection<Class<?>> classes, 
+                                                         Class<? extends Annotation> serviceClassAnnotation) {
+        AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
+        final List< Object > providers = new ArrayList< Object >();
+        for (final Class< ? > clazz: classes) {
+            if (serviceClassAnnotation != null && clazz.getAnnotation(serviceClassAnnotation) == null) {
+                continue;
+            }
+            Object bean = null;
+            try {
+                bean = beanFactory.createBean(clazz, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+            } catch (Exception ex) {
+                bean = beanFactory.createBean(clazz);
             }
-            return providers;
+            providers.add(bean);
         }
+        return providers;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java
new file mode 100644
index 0000000..87931f8
--- /dev/null
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/AbstractJaxRsClientConfiguration.java
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.client.spring;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxrs.client.Client;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.spring.JaxRsConfig;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Import;
+
+@Import(JaxRsConfig.class)
+public abstract class AbstractJaxRsClientConfiguration implements ApplicationContextAware {
+
+    protected ApplicationContext context;
+    @Autowired
+    private Bus bus;
+    @Value("${cxf.jaxrs.client.address}")
+    private String address;
+    
+    protected Client createClient() {
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setBus(bus);        
+        bean.setAddress(address);
+        setJaxrsResources(bean);
+        return bean.create();
+    }
+    
+    protected abstract void setJaxrsResources(JAXRSClientFactoryBean factory);
+
+    
+    @Override
+    public void setApplicationContext(ApplicationContext ac) throws BeansException {
+        this.context = ac;
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsProxyClient.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsProxyClient.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsProxyClient.java
new file mode 100644
index 0000000..3bc1512
--- /dev/null
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsProxyClient.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.client.spring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Import;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Import(JaxRsClientClassesScanConfiguration.class)
+public @interface EnableJaxRsProxyClient {
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsWebClient.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsWebClient.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsWebClient.java
new file mode 100644
index 0000000..53c0521
--- /dev/null
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/EnableJaxRsWebClient.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.client.spring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Import;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Import(WebClientConfiguration.class)
+public @interface EnableJaxRsWebClient {
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JAXRSClientFactoryBeanDefinitionParser.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JAXRSClientFactoryBeanDefinitionParser.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JAXRSClientFactoryBeanDefinitionParser.java
index 661d621..95259c2 100644
--- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JAXRSClientFactoryBeanDefinitionParser.java
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JAXRSClientFactoryBeanDefinitionParser.java
@@ -21,6 +21,7 @@ package org.apache.cxf.jaxrs.client.spring;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -161,4 +162,27 @@ public class JAXRSClientFactoryBeanDefinitionParser extends AbstractFactoryBeanD
         }
     }
 
+    static Class<?> getServiceClass(Collection<Class<?>> rootClasses) {
+        for (Class<?> cls : rootClasses) {
+            if (cls.isInterface()) {
+                return cls;
+            }
+        }
+        return rootClasses.iterator().next();
+    }
+    static List<Object> getProviders(ApplicationContext context, Collection<Class<?>> providerClasses) {
+        List<Object> providers = new LinkedList<Object>();
+        AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
+        for (final Class< ? > providerClass: providerClasses) {
+            Object bean = null;
+            try {
+                bean = beanFactory.createBean(providerClass, 
+                                       AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+            } catch (Exception ex) {
+                bean = beanFactory.createBean(providerClass);
+            }
+            providers.add(bean);
+        }
+        return providers;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsClientClassesScanConfiguration.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsClientClassesScanConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsClientClassesScanConfiguration.java
new file mode 100644
index 0000000..45a7cef
--- /dev/null
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/JaxRsClientClassesScanConfiguration.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.client.spring;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.common.util.ClasspathScanner;
+import org.apache.cxf.jaxrs.client.Client;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.service.factory.ServiceConstructionException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+
+public class JaxRsClientClassesScanConfiguration extends AbstractJaxRsClientConfiguration {
+    @Value("${cxf.jaxrs.client.classes-scan-packages}")
+    private String scanPackages;
+    
+    @Bean
+    protected Client jaxRsProxyClient() {
+        return super.createClient();
+    }
+    
+    protected void setJaxrsResources(JAXRSClientFactoryBean factory) {
+        try {
+            final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes = 
+                ClasspathScanner.findClasses(scanPackages, Path.class, Provider.class);
+            
+            factory.setServiceClass(
+                JAXRSClientFactoryBeanDefinitionParser.getServiceClass(classes.get(Path.class)));
+            factory.setProviders(
+                JAXRSClientFactoryBeanDefinitionParser.getProviders(context, classes.get(Provider.class)));
+        } catch (Exception ex) {
+            throw new ServiceConstructionException(ex);    
+        }
+        
+    }
+
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/a2d869b5/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/WebClientConfiguration.java
----------------------------------------------------------------------
diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/WebClientConfiguration.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/WebClientConfiguration.java
new file mode 100644
index 0000000..72a5164
--- /dev/null
+++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spring/WebClientConfiguration.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.client.spring;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.common.util.ClasspathScanner;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.client.Client;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.service.factory.ServiceConstructionException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+
+public class WebClientConfiguration extends AbstractJaxRsClientConfiguration {
+
+    @Value("${cxf.jaxrs.client.classes-scan-packages:''")
+    private String scanPackages;
+    
+    @Bean
+    protected Client jaxRsWebClient() {
+        return super.createClient();
+    }
+    
+    @Override
+    protected void setJaxrsResources(JAXRSClientFactoryBean factory) {
+        factory.setServiceClass(WebClient.class);
+        
+        if (!StringUtils.isEmpty(scanPackages)) {
+            try {
+                final Map< Class< ? extends Annotation >, Collection< Class< ? > > > classes = 
+                    ClasspathScanner.findClasses(scanPackages, Provider.class);
+                
+                factory.setProviders(
+                    JAXRSClientFactoryBeanDefinitionParser.getProviders(context, classes.get(Provider.class)));
+            } catch (Exception ex) {
+                throw new ServiceConstructionException(ex);
+            }
+        }
+    }
+
+    
+}