package org.jboss.resteasy.client.spring; import org.apache.http.client.HttpClient; import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; import org.jboss.resteasy.plugins.providers.RegisterBuiltin; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import java.net.URI; /** * {@link org.springframework.beans.factory.FactoryBean} to generate a client * proxy from a REST annotated interface. * <p/> * <p> * Example: The following spring xml configuration snippet makes a bean with the * id echoClient. The bean is a generated proxy of the a.b.c.Echo interface to * access the remote service on http://server.far.far.away:8080/echo base URI. * </p> * <p/> * <pre> * <bean id="echoClient" class="org.jboss.resteasy.client.spring.RestClientProxyFactoryBean" * p:serviceInterface="a.b.c.Echo" p:baseUri="http://server.far.far.away:8080/echo" /> * </pre> * * @author Attila Kiraly * @param <T> * The type representing the client interface. */ public class RestClientProxyFactoryBean<T> implements FactoryBean<T>, InitializingBean { private Class<T> serviceInterface; private URI baseUri; private T client; private HttpClient httpClient; private ClientHttpEngine clientEngine; private ResteasyProviderFactory resteasyProviderFactory; /* * (non-Javadoc) * * @see org.springframework.beans.factory.FactoryBean#getObject() */ public T getObject() throws Exception { return client; } /* * (non-Javadoc) * * @see org.springframework.beans.factory.FactoryBean#getObjectType() */ public Class<T> getObjectType() { return serviceInterface; } /* * (non-Javadoc) * * @see org.springframework.beans.factory.FactoryBean#isSingleton() */ public boolean isSingleton() { return true; } /* * (non-Javadoc) * * @see * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ public void afterPropertiesSet() throws Exception { if (resteasyProviderFactory == null) resteasyProviderFactory = ResteasyProviderFactory.getInstance(); RegisterBuiltin.register(resteasyProviderFactory); ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder(); clientBuilder.providerFactory(resteasyProviderFactory); if (clientEngine == null) { if (httpClient == null) { clientEngine = new ApacheHttpClient4Engine(); } else { clientEngine = new ApacheHttpClient4Engine(httpClient); } } ResteasyWebTarget target = clientBuilder.httpEngine(clientEngine).build().target(baseUri); client = target.proxy(serviceInterface); } public Class<T> getServiceInterface() { return serviceInterface; } /** * This is a mandatory property that needs to be set. * * @param serviceInterface the interface for which a proxy is needed to be generated. */ public void setServiceInterface(Class<T> serviceInterface) { this.serviceInterface = serviceInterface; } public URI getBaseUri() { return baseUri; } /** * This is a mandatory property that needs to be set. * * @param baseUri the remote service base address. */ public void setBaseUri(URI baseUri) { this.baseUri = baseUri; } public HttpClient getHttpClient() { return httpClient; } /** * Optional property. If this property is set and {@link #clientEngine} is * null, this will be used by proxy generation. This could be useful for * example when you want to use a * {@link org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager} * instead of a * {@link org.apache.http.impl.conn.SingleClientConnManager} which * is the default in {@link org.apache.http.client.HttpClient}. * * @param httpClient the instance to be used by proxy generation * @see ProxyFactory#create(Class, URI, HttpClient, ResteasyProviderFactory) */ public void setHttpClient(HttpClient httpClient) { this.httpClient = httpClient; } public ClientHttpEngine getClientEngine() { return clientEngine; } /** * Optional property for advanced usage. If this property is set it will be * used by proxy generation. If this property is set the {@link #httpClient} * property is ignored. * * @param clientExecutor the instance to be used by proxy generation * @see ProxyFactory#create(Class, URI, ClientExecutor, * ResteasyProviderFactory) */ public void setClientExecutor(ClientHttpEngine clientEngine) { this.clientEngine = clientEngine; } public ResteasyProviderFactory getResteasyProviderFactory() { return resteasyProviderFactory; } /** * Optional property for advanced usage. For the most cases this property is * not needed to be set. * * @param resteasyProviderFactory the instance to be used by proxy generation. */ public void setResteasyProviderFactory( ResteasyProviderFactory resteasyProviderFactory) { this.resteasyProviderFactory = resteasyProviderFactory; } }