@ -5,9 +5,7 @@ import java.util.HashSet;
@@ -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,29 +48,44 @@ public class FeignClientScanRegistrar extends FeignConfiguration
@@ -50,29 +48,44 @@ public class FeignClientScanRegistrar extends FeignConfiguration
@Override
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 ) ;
}
Set < String > basePackages = getBasePackages ( importingClassMetadata ) ;
ClassPathScanningCandidateComponentProvider scanner = getScanner ( ) ;
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 ( ) ) {
basePackages . add ( ClassUtils . getPackageName ( importingClassMetadata . getClassName ( ) ) ) ;
public BeanDefinitionHolder createBeanDefinition ( AnnotationMetadata annotationMetadata ) {
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
protected boolean isCandidateComponent ( AnnotatedBeanDefinition beanDefinition ) {
@ -95,61 +108,31 @@ public class FeignClientScanRegistrar extends FeignConfiguration
@@ -95,61 +108,31 @@ public class FeignClientScanRegistrar extends FeignConfiguration
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 ;
Class < ? > type ;
String schemeName ;
protected Set < String > getBasePackages ( AnnotationMetadata importingClassMetadata ) {
Map < String , Object > attributes = importingClassMetadata
. getAnnotationAttributes ( FeignClientScan . class . getCanonicalName ( ) ) ;
@Override
public Object getObject ( ) throws Exception {
if ( ! schemeName . startsWith ( "http" ) ) {
schemeName = "http://" + schemeName ;
Set < String > basePackages = new HashSet < > ( ) ;
for ( String pkg : ( String [ ] ) attributes . get ( "value" ) ) {
if ( StringUtils . hasText ( pkg ) ) {
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
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 ;
}
}