Browse Source

Migrate SpringClientFactory and FeignClientFactory

Now uses spring-cloud-context NamedContextFactory.

see https://github.com/spring-cloud/spring-cloud-commons/issues/69
pull/6/head
Spencer Gibb 9 years ago
parent
commit
bad20d3fcc
  1. 106
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactory.java
  2. 4
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java
  3. 6
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java
  4. 97
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java

106
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactory.java

@ -16,114 +16,20 @@ @@ -16,114 +16,20 @@
package org.springframework.cloud.netflix.feign;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.cloud.context.named.NamedContextFactory;
/**
* A factory that creates client, load balancer and client configuration instances. It
* creates a Spring ApplicationContext per client name, and extracts the beans that it
* A factory that creates instances of feign classes. It * creates a Spring
* ApplicationContext per client name, and extracts the beans that it
* needs from there.
*
* @author Spencer Gibb
* @author Dave Syer
*/
public class FeignClientFactory implements DisposableBean, ApplicationContextAware {
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
private Map<String, FeignClientSpecification> configurations = new ConcurrentHashMap<>();
private ApplicationContext parent;
@Override
public void setApplicationContext(ApplicationContext parent) throws BeansException {
this.parent = parent;
}
public void setConfigurations(List<FeignClientSpecification> configurations) {
for (FeignClientSpecification client : configurations) {
this.configurations.put(client.getName(), client);
}
}
@Override
public void destroy() {
Collection<AnnotationConfigApplicationContext> values = this.contexts.values();
this.contexts.clear();
for (AnnotationConfigApplicationContext context : values) {
context.close();
}
}
private AnnotationConfigApplicationContext getContext(String name) {
if (!this.contexts.containsKey(name)) {
synchronized (this.contexts) {
if (!this.contexts.containsKey(name)) {
this.contexts.put(name, createContext(name));
}
}
}
return this.contexts.get(name);
}
private AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (this.configurations.containsKey(name)) {
for (Class<?> configuration : this.configurations.get(name)
.getConfiguration()) {
context.register(configuration);
}
}
for (Entry<String, FeignClientSpecification> entry : this.configurations
.entrySet()) {
if (entry.getKey().startsWith("default.")) {
for (Class<?> configuration : entry.getValue().getConfiguration()) {
context.register(configuration);
}
}
}
context.register(PropertyPlaceholderAutoConfiguration.class,
FeignClientsConfiguration.class);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
"feign",
Collections.<String, Object> singletonMap("feign.client.name", name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
}
context.refresh();
return context;
}
public <C> C getInstance(String name, Class<C> type) {
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
type).length > 0) {
return context.getBean(type);
}
return null;
}
public class FeignClientFactory extends NamedContextFactory<FeignClientSpecification> {
public <C> Map<String, C> getInstances(String name, Class<C> type) {
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
type).length > 0) {
return BeanFactoryUtils.beansOfTypeIncludingAncestors(context, type);
}
return null;
public FeignClientFactory() {
super(FeignClientsConfiguration.class, "feign", "feign.client.name");
}
}

4
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.cloud.netflix.feign;
import org.springframework.cloud.context.named.NamedContextFactory;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -26,7 +28,7 @@ import lombok.NoArgsConstructor; @@ -26,7 +28,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FeignClientSpecification {
public class FeignClientSpecification implements NamedContextFactory.Specification {
private String name;

6
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java

@ -16,15 +16,19 @@ @@ -16,15 +16,19 @@
package org.springframework.cloud.netflix.ribbon;
import org.springframework.cloud.context.named.NamedContextFactory;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Dave Syer
*/
@Data
@AllArgsConstructor
public class RibbonClientSpecification {
@NoArgsConstructor
public class RibbonClientSpecification implements NamedContextFactory.Specification {
private String name;

97
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java

@ -16,22 +16,9 @@ @@ -16,22 +16,9 @@
package org.springframework.cloud.netflix.ribbon;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.cloud.context.named.NamedContextFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MapPropertySource;
import com.netflix.client.IClient;
import com.netflix.client.IClientConfigAware;
@ -46,32 +33,10 @@ import com.netflix.loadbalancer.ILoadBalancer; @@ -46,32 +33,10 @@ import com.netflix.loadbalancer.ILoadBalancer;
* @author Spencer Gibb
* @author Dave Syer
*/
public class SpringClientFactory implements DisposableBean, ApplicationContextAware {
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
private Map<String, RibbonClientSpecification> configurations = new ConcurrentHashMap<>();
private ApplicationContext parent;
@Override
public void setApplicationContext(ApplicationContext parent) throws BeansException {
this.parent = parent;
}
public class SpringClientFactory extends NamedContextFactory<RibbonClientSpecification> {
public void setConfigurations(List<RibbonClientSpecification> configurations) {
for (RibbonClientSpecification client : configurations) {
this.configurations.put(client.getName(), client);
}
}
@Override
public void destroy() {
Collection<AnnotationConfigApplicationContext> values = this.contexts.values();
this.contexts.clear();
for (AnnotationConfigApplicationContext context : values) {
context.close();
}
public SpringClientFactory() {
super(RibbonClientConfiguration.class, "ribbon", "ribbon.client.name");
}
/**
@ -106,51 +71,8 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw @@ -106,51 +71,8 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
return getInstance(serviceId, RibbonLoadBalancerContext.class);
}
private AnnotationConfigApplicationContext getContext(String name) {
if (!this.contexts.containsKey(name)) {
synchronized (this.contexts) {
if (!this.contexts.containsKey(name)) {
this.contexts.put(name, createContext(name));
}
}
}
return this.contexts.get(name);
}
private AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (this.configurations.containsKey(name)) {
for (Class<?> configuration : this.configurations.get(name)
.getConfiguration()) {
context.register(configuration);
}
}
for (Entry<String, RibbonClientSpecification> entry : this.configurations
.entrySet()) {
if (entry.getKey().startsWith("default.")) {
for (Class<?> configuration : entry.getValue().getConfiguration()) {
context.register(configuration);
}
}
}
context.register(PropertyPlaceholderAutoConfiguration.class,
RibbonClientConfiguration.class);
context.getEnvironment()
.getPropertySources()
.addFirst(
new MapPropertySource("ribbon",
Collections.<String, Object> singletonMap(
"ribbon.client.name", name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
}
context.refresh();
return context;
}
private <C> C instantiateWithConfig(AnnotationConfigApplicationContext context,
Class<C> clazz, IClientConfig config) {
Class<C> clazz, IClientConfig config) {
C result = null;
if (IClientConfigAware.class.isAssignableFrom(clazz)) {
IClientConfigAware obj = (IClientConfigAware) BeanUtils.instantiate(clazz);
@ -178,12 +100,13 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw @@ -178,12 +100,13 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
}
public <C> C getInstance(String name, Class<C> type) {
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type).length > 0) {
return context.getBean(type);
C instance = super.getInstance(name, type);
if (instance != null) {
return instance;
}
IClientConfig config = getInstance(name, IClientConfig.class);
return instantiateWithConfig(context, type, config);
return instantiateWithConfig(getContext(name), type, config);
}
}

Loading…
Cancel
Save