In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about the role of EnableFeignClients in Feign. The article is rich in content and analyzes and narrates it from a professional point of view. I hope you can get something after reading this article.
Springcloud-openfeign-core-2.1.1.release.
When using feign in springcloud, the name of the following List-1,FeignClient is the service name, and the physical address is automatically obtained from the Eureka.
List-1
@ FeignClient (name= "UserProvider") public interface UserProvider {...}
How is this implemented in Springcloud?
This starts with @ EnableFeignClients. The following List-2,Import comments introduce FeignClientsRegistrar-- to implement the ImportBeanDefinitionRegistrar interface, so that springboot will handle the FeignClientsRegistrar.
List-2
@ Retention (RetentionPolicy.RUNTIME) @ Target (ElementType.TYPE) @ Documented@Import (FeignClientsRegistrar.class) public @ interface EnableFeignClients {String [] value () default {}; String [] basePackages () default {}; Class [] basePackageClasses () default {}; Class [] defaultConfiguration () default {}; Class [] clients () default {};}
As shown in figure 1 below, FeignClientsRegistrar does not have a complex inheritance relationship, and the key class is the registerBeanDefinitions implementation of ImportBeanDefinitionRegistrar.
Figure 1
The following List-3 is divided into two steps. First, the registerDefaultConfiguration method registers the defaultConfiguration of EnableFeignClients with the Spring container, and then the registerFeignClients method registers the interface annotated by FeignClient with the Spring container.
List-3
Overridepublic void registerBeanDefinitions (AnnotationMetadata metadata, BeanDefinitionRegistry registry) {registerDefaultConfiguration (metadata, registry); registerFeignClients (metadata, registry);}
Take a look at the registerDefaultConfiguration method, as follows: List-4
Get all the properties of the EnableFeignClients, and then register the defaultConfiguration in the Spring container if it contains defaultConfiguration
Methods in registerClientConfiguration, the BeanDefinition of FeignClientSpecification type is constructed by using Builder pattern. FeignClientSpecification implements the NamedContextFactory.Specification interface, and the property has a configuration of type name and Class.
List-4
Private void registerDefaultConfiguration (AnnotationMetadata metadata,BeanDefinitionRegistry registry) {Map defaultAttrs = metadata .getAnnotationAttributes (EnableFeignClients.class.getName (), true); if (defaultAttrs! = null & & defaultAttrs.containsKey ("defaultConfiguration")) {String name; if (metadata.hasEnclosingClass ()) {name = "default." + metadata.getEnclosingClassName ();} else {name = "default." + metadata.getClassName () } registerClientConfiguration (registry, name, defaultAttrs.get ("defaultConfiguration"));}} private void registerClientConfiguration (BeanDefinitionRegistry registry, Object name,Object configuration) {BeanDefinitionBuilder builder = BeanDefinitionBuilder .genericBeanDefinition (FeignClientSpecification.class); builder.addConstructorArgValue (name); builder.addConstructorArgValue (configuration); registry.registerBeanDefinition (name + "." + FeignClientSpecification.class.getSimpleName (), builder.getBeanDefinition ());}
In the registerFeignClients method, the implementation is more complex, as follows: List-5
List-5
Public void registerFeignClients (AnnotationMetadata metadata, BeanDefinitionRegistry registry) {ClassPathScanningCandidateComponentProvider scanner = getScanner (); / / 1 scanner.setResourceLoader (this.resourceLoader); Set basePackages; Map attrs = metadata .getAnnotationAttributes (EnableFeignClients.class.getName ()); / / 2 AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter (FeignClient.class); / / 3 final Class [] clients = attrs = null? Null: (Class []) attrs.get ("clients"); if (clients = = null | | clients.length = = 0) {/ / 4 scanner.addIncludeFilter (annotationTypeFilter); basePackages = getBasePackages (metadata);} else {/ / 5 final Set clientClasses = new HashSet (); basePackages = new HashSet (); for (Class clazz: clients) {basePackages.add (ClassUtils.getPackageName (clazz)) ClientClasses.add (clazz.getCanonicalName ());} AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter () {@ Override protected boolean match (ClassMetadata metadata) {String cleaned = metadata.getClassName () .replaceAll ("\\ $", "."); return clientClasses.contains (cleaned);}} Scanner.addIncludeFilter (new AllTypeFilter (Arrays.asList (filter, annotationTypeFilter));} 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 AnnotationMetadata annotationMetadata = beanDefinition.getMetadata (); Assert.isTrue (annotationMetadata.isInterface (), "@ FeignClient can only be specified on an interface"); Map attributes = annotationMetadata .getAnnotationAttributes (FeignClient.class.getCanonicalName ()); String name = getClientName (attributes) RegisterClientConfiguration (registry, name, attributes.get ("configuration")); / / 6 registerFeignClient (registry, annotationMetadata, attributes); / / 7}
Get the ClassPathScanner at 1 to scan the classpath
Get all the properties of EnableFeignClients at 2
Construct an AnnotationTypeFilter at 3, and the constructor parameter is FeignClient, which is used to filter out classes that contain only FeignClient
Get the clients attribute value of EnableFeignClients, and if it is empty at 4, get the package path where EnableFeignClients is located (if basePackageClasses is not set)
5, that is, if the clients property of the EnableFeignClients is not empty, it is traversed and put into the collection, and the package road surface where the client is located is obtained and added to the basePacakges; the AbstractClassTestingTypeFilter is constructed, which adds a filter condition, that is, the interface marked with FeignClient comments, which must be in the clients of the EnableFeignClients.
Traverse the basePackages to get the eligible classes under each package, get the definition value of the FeignClient at the corresponding beanDefinition,6, and register it in the spring container through FeignClientSpecification. What is interesting is that the class that checks the FeignClient annotation here must be an interface, otherwise an error will be reported.
7 encapsulate the interface annotated by FeignClient into FeignClientFactoryBean, as you know in FactoryBean, all the interfaces in Spring are encapsulated in this.
The above is what the role of EnableFeignClients in Feign is shared by the editor. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.