springcloud-loadbalancer-03

405 阅读2分钟

🤓目前为止我们看下都介绍了哪些东西,梳理一下。

png3.png 一下子干掉了好多啊!后边还有呢!😀

👉上面提到过@LoadBalancerClient@LoadBalancerClients

/**
 * Declarative configuration for a load balancer client. Add this annotation to any
 * <code>@Configuration</code> and then inject a {@link LoadBalancerClientFactory} to
 * access the client that is created.
 *
 * @author Dave Syer
 */
@Configuration(proxyBeanMethods = false)
@Import(LoadBalancerClientConfigurationRegistrar.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoadBalancerClient {

   /**
    * Synonym for name (the name of the client).
    *
    * @see #name()
    * @return the name of the load balancer client
    */
   //name 和 value 都是微服务名称
   @AliasFor("name")
   String value() default "";

   /**
    * The name of the load balancer client, uniquely identifying a set of client
    * resources, including a load balancer.
    * @return the name of the load balancer client
    */
   @AliasFor("value")
   String name() default "";

   /**
    * A custom <code>@Configuration</code> for the load balancer client. Can contain
    * override <code>@Bean</code> definition for the pieces that make up the client.
    *
    * @see LoadBalancerClientConfiguration for the defaults
    * @return configuration classes for the load balancer client.
    */
   //这个微服务的配置
   Class<?>[] configuration() default {};

}

从官方注释我们可以看出,该注解为负载均衡客户端声明了一个配置,添加该注解的配置将会被注入到LoadBalancerClientFactory中。我们关注下@Import(LoadBalancerClientConfigurationRegistrar.class)这个。LoadBalancerClientConfigurationRegistrar将会被加入到容器。

/**
 * 完成对@LoadBalanceClient或者@LoadBalanceClients注解标注类的解析
 * @author Dave Syer
 */
public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {

   //解析@LoadBalanceClient或者@LoadBalanceClients的参数
   private static String getClientName(Map<String, Object> client) {
      if (client == null) {
         return null;
      }
      String value = (String) client.get("value");
      if (!StringUtils.hasText(value)) {
         value = (String) client.get("name");
      }
      if (StringUtils.hasText(value)) {
         return value;
      }
      throw new IllegalStateException("Either 'name' or 'value' must be provided in @LoadBalancerClient");
   }

   //利用BeanDefinitionBuilder创建LoadBalancerClientSpecification类型的Bean,这些Bean
   //将自动注入到LoadBalancerAutoConfiguration类的configurations中,最终会注入到LoadBalancerClientFactory中
   private static void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
         Object configuration) {
      BeanDefinitionBuilder builder = BeanDefinitionBuilder
            .genericBeanDefinition(LoadBalancerClientSpecification.class);
      builder.addConstructorArgValue(name);
      builder.addConstructorArgValue(configuration);
      registry.registerBeanDefinition(name + ".LoadBalancerClientSpecification", builder.getBeanDefinition());
   }

   @Override
   //注册Bean
   public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
      Map<String, Object> attrs = metadata.getAnnotationAttributes(LoadBalancerClients.class.getName(), true);
      if (attrs != null && attrs.containsKey("value")) {
         AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
         for (AnnotationAttributes client : clients) {
            registerClientConfiguration(registry, getClientName(client), client.get("configuration"));
         }
      }
      if (attrs != null && attrs.containsKey("defaultConfiguration")) {
         String name;
         if (metadata.hasEnclosingClass()) {
            name = "default." + metadata.getEnclosingClassName();
         }
         else {
            name = "default." + metadata.getClassName();
         }
         registerClientConfiguration(registry, name, attrs.get("defaultConfiguration"));
      }
      Map<String, Object> client = metadata.getAnnotationAttributes(LoadBalancerClient.class.getName(), true);
      //以下是将我们自定义的配置类加入到容器中
      String name = getClientName(client);
      if (name != null) {
         registerClientConfiguration(registry, name, client.get("configuration"));
      }
   }

}

我们从registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) 开始看起

它先解析了注解的配置属性,并使用registerClientConfiguration(registry, getClientName(client), client.get("configuration"));来注册配置,主要时利用BeanDefinitionBuilder创建LoadBalancerClientSpecification类型的Bean,这些Bean将自动注入到LoadBalancerAutoConfiguration类的configurations中,最终会注入到LoadBalancerClientFactory中。这里就成功反映了我们在上面切换负载均衡算法时的配置。其他的部分正如我所注释那样,主要是默认配置和自定义配置的注册。

至于@LoadBalanceClients基本差不多,不在赘述了。

这下就完成了大半了 png4.png