Migrate SpringClientFactory and FeignClientFactory
Now uses spring-cloud-context NamedContextFactory. see https://github.com/spring-cloud/spring-cloud-commons/issues/69
This commit is contained in:
@@ -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 {
|
||||
public class FeignClientFactory extends NamedContextFactory<FeignClientSpecification> {
|
||||
|
||||
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 <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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class FeignClientSpecification {
|
||||
public class FeignClientSpecification implements NamedContextFactory.Specification {
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class SpringClientFactory implements DisposableBean, ApplicationContextAware {
|
||||
public class SpringClientFactory extends NamedContextFactory<RibbonClientSpecification> {
|
||||
|
||||
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 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
|
||||
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
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user