Browse Source

Polish

pull/6/head
Spencer Gibb 10 years ago
parent
commit
92a3454237
  1. 36
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java
  2. 111
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java

36
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java

@ -0,0 +1,36 @@
package org.springframework.cloud.netflix.feign;
import lombok.Data;
import org.springframework.beans.factory.FactoryBean;
/**
* @author Spencer Gibb
*/
@Data
class FeignClientFactoryBean extends FeignConfiguration implements FactoryBean<Object> {
boolean loadbalance;
Class<?> type;
String schemeName;
@Override
public Object getObject() throws Exception {
if (!schemeName.startsWith("http")) {
schemeName = "http://"+schemeName;
}
if (loadbalance) {
return loadBalance(type, schemeName);
}
return feign().target(type, schemeName);
}
@Override
public Class<?> getObjectType() {
return type;
}
@Override
public boolean isSingleton() {
return true;
}
}

111
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java

@ -5,9 +5,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import lombok.Data;
import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.BeanDefinitionHolder;
@ -50,29 +48,44 @@ public class FeignClientScanRegistrar extends FeignConfiguration
@Override @Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> componentScan = importingClassMetadata
.getAnnotationAttributes(FeignClientScan.class.getCanonicalName());
Set<String> basePackages = new HashSet<String>(); Set<String> basePackages = getBasePackages(importingClassMetadata);
for (String pkg : (String[]) componentScan.get("value")) {
if (StringUtils.hasText(pkg)) { ClassPathScanningCandidateComponentProvider scanner = getScanner();
basePackages.add(pkg); scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
} scanner.setResourceLoader(resourceLoader);
for (String basePackage : basePackages) {
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition) {
//verify annotated class is an interface
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
} }
for (String pkg : (String[]) componentScan.get("basePackages")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
} }
} }
for (Class<?> clazz : (Class[]) componentScan.get("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
} }
if (basePackages.isEmpty()) { public BeanDefinitionHolder createBeanDefinition(AnnotationMetadata annotationMetadata) {
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName())); Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
String className = annotationMetadata.getClassName();
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
definition.addPropertyValue("loadbalance", attributes.get("loadbalance"));
definition.addPropertyValue("type", className);
definition.addPropertyValue("schemeName", attributes.get("value"));
String beanName = StringUtils.uncapitalize(className.substring(className.lastIndexOf(".") + 1));
return new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
} }
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) { protected ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false) {
@Override @Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
@ -95,61 +108,31 @@ public class FeignClientScanRegistrar extends FeignConfiguration
return false; return false;
} }
}; };
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
scanner.setResourceLoader(resourceLoader);
for (String basePackage : basePackages) {
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignFactoryBean.class);
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
String className = annotationMetadata.getClassName();
definition.addPropertyValue("loadbalance", attributes.get("loadbalance"));
definition.addPropertyValue("type", className);
definition.addPropertyValue("schemeName", attributes.get("value"));
String beanName = StringUtils.uncapitalize(className.substring(className.lastIndexOf(".")+1));
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
}
}
} }
}
@Data
public static class FeignFactoryBean extends FeignConfiguration implements FactoryBean<Object> {
boolean loadbalance; protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
Class<?> type; Map<String, Object> attributes = importingClassMetadata
String schemeName; .getAnnotationAttributes(FeignClientScan.class.getCanonicalName());
@Override Set<String> basePackages = new HashSet<>();
public Object getObject() throws Exception { for (String pkg : (String[]) attributes.get("value")) {
if (!schemeName.startsWith("http")) { if (StringUtils.hasText(pkg)) {
schemeName = "http://"+schemeName; basePackages.add(pkg);
} }
if (loadbalance) {
return loadBalance(type, schemeName);
} }
return feign().target(type, schemeName); for (String pkg : (String[]) attributes.get("basePackages")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
} }
}
@Override for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
public Class<?> getObjectType() { basePackages.add(ClassUtils.getPackageName(clazz));
return type;
} }
@Override if (basePackages.isEmpty()) {
public boolean isSingleton() { basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
return true;
} }
return basePackages;
} }
} }

Loading…
Cancel
Save