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. 135
      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;
}
}

135
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,106 +48,91 @@ 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>();
for (String pkg : (String[]) componentScan.get("value")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
}
}
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()) {
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
}
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) { Set<String> basePackages = getBasePackages(importingClassMetadata);
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
if (beanDefinition.getMetadata().isIndependent()) {
// TODO until SPR-11711 will be resolved
if (beanDefinition.getMetadata().isInterface() &&
beanDefinition.getMetadata().getInterfaceNames().length == 1 &&
Annotation.class.getName().equals(beanDefinition.getMetadata().getInterfaceNames()[0])) {
try {
Class<?> target = ClassUtils.forName(beanDefinition.getMetadata().getClassName(), classLoader);
return !target.isAnnotation();
}
catch (Exception e) {
logger.error("Could not load target class: " + beanDefinition.getMetadata().getClassName(), e);
}
}
return true;
}
return false;
}
};
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class)); scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
scanner.setResourceLoader(resourceLoader); scanner.setResourceLoader(resourceLoader);
for (String basePackage : basePackages) { for (String basePackage : basePackages) {
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage); Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
for (BeanDefinition candidateComponent : candidateComponents) { for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition) { if (candidateComponent instanceof AnnotatedBeanDefinition) {
//verify annotated class is an interface
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent; AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignFactoryBean.class);
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata(); AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface"); Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName()); BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
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); BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
} }
} }
} }
} }
@Data public BeanDefinitionHolder createBeanDefinition(AnnotationMetadata annotationMetadata) {
public static class FeignFactoryBean extends FeignConfiguration implements FactoryBean<Object> { 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);
}
protected ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
if (beanDefinition.getMetadata().isIndependent()) {
// TODO until SPR-11711 will be resolved
if (beanDefinition.getMetadata().isInterface() &&
beanDefinition.getMetadata().getInterfaceNames().length == 1 &&
Annotation.class.getName().equals(beanDefinition.getMetadata().getInterfaceNames()[0])) {
try {
Class<?> target = ClassUtils.forName(beanDefinition.getMetadata().getClassName(), classLoader);
return !target.isAnnotation();
}
catch (Exception e) {
logger.error("Could not load target class: " + beanDefinition.getMetadata().getClassName(), e);
}
}
return true;
}
return false;
}
};
}
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); for (String pkg : (String[]) attributes.get("basePackages")) {
if (StringUtils.hasText(pkg)) {
basePackages.add(pkg);
} }
return feign().target(type, schemeName);
} }
for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
@Override basePackages.add(ClassUtils.getPackageName(clazz));
public Class<?> getObjectType() {
return type;
} }
@Override if (basePackages.isEmpty()) {
public boolean isSingleton() { basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
return true;
} }
return basePackages;
} }
} }

Loading…
Cancel
Save