diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java new file mode 100644 index 00000000..9f98be95 --- /dev/null +++ b/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 { + + 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; + } +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java index 6af944f1..0b6bd20d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java +++ b/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.Set; -import lombok.Data; import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -50,106 +48,91 @@ public class FeignClientScanRegistrar extends FeignConfiguration @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { - Map componentScan = importingClassMetadata - .getAnnotationAttributes(FeignClientScan.class.getCanonicalName()); - - Set basePackages = new HashSet(); - 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) { - - @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; - } - }; + Set basePackages = getBasePackages(importingClassMetadata); + ClassPathScanningCandidateComponentProvider scanner = getScanner(); scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class)); - scanner.setResourceLoader(resourceLoader); for (String basePackage : basePackages) { Set candidateComponents = scanner.findCandidateComponents(basePackage); for (BeanDefinition candidateComponent : candidateComponents) { if (candidateComponent instanceof AnnotatedBeanDefinition) { + //verify annotated class is an interface 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 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); + BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata); BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); } } } } - @Data - public static class FeignFactoryBean extends FeignConfiguration implements FactoryBean { + public BeanDefinitionHolder createBeanDefinition(AnnotationMetadata annotationMetadata) { + Map 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; - Class type; - String schemeName; + protected Set getBasePackages(AnnotationMetadata importingClassMetadata) { + Map attributes = importingClassMetadata + .getAnnotationAttributes(FeignClientScan.class.getCanonicalName()); - @Override - public Object getObject() throws Exception { - if (!schemeName.startsWith("http")) { - schemeName = "http://"+schemeName; + Set basePackages = new HashSet<>(); + for (String pkg : (String[]) attributes.get("value")) { + if (StringUtils.hasText(pkg)) { + 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); } - - @Override - public Class getObjectType() { - return type; + for (Class clazz : (Class[]) attributes.get("basePackageClasses")) { + basePackages.add(ClassUtils.getPackageName(clazz)); } - @Override - public boolean isSingleton() { - return true; + if (basePackages.isEmpty()) { + basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName())); } + return basePackages; } + }