zoukankan      html  css  js  c++  java
  • Spring 通过@Import实现Bean的注册

    今天看到一个神奇的用法, Spring可以通过@Import导入实现了ImportBeanDefinitionRegistrar接口的类来注册那个类.
    ImportBeanDefinitionRegistrar接口是用来被实现以使Spring在处理Configuration的时候注册额外的bean. @Import注解可以引入一个Configuration类, 或ImportSelector实现类以根据特定条件导入合适的类. 其次就是可以引入实现了ImportBeanDefinitionRegistrar接口的类来直接注册类.

    当然, 除了ImportBeanDefinitionRegistrar实现类, 还可以使用ClassPathBeanDefinitionScanner这个扫描器, 获取需要注册的bean. ClassPathBeanDefinitionScanner继承了ClassPathScanningCandidateComponentProvider, 其中有两个TypeFilter, includeFilters和excludeFilters, 可以用来过滤类.

    比如以下即实现了ImportBeanDefinitionRegistrar接口:

    class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
      public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        this.registerDefaultConfiguration(metadata, registry);
        this.registerFeignClients(metadata, registry);
      }
    }
    

    在registerFeignClients使用ClassPathScanningCandidateComponentProvider来过滤类, 注入包含了@FeignClient注解的类.

      public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        ClassPathScanningCandidateComponentProvider scanner = this.getScanner();
        scanner.setResourceLoader(this.resourceLoader);
        Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FeignClient.class);
        Class<?>[] clients = attrs == null ? null : (Class[])((Class[])attrs.get("clients"));
        Object basePackages;
        if (clients != null && clients.length != 0) {
          final Set<String> clientClasses = new HashSet();
          basePackages = new HashSet();
          Class[] var9 = clients;
          int var10 = clients.length;
    
          for(int var11 = 0; var11 < var10; ++var11) {
            Class<?> clazz = var9[var11];
            ((Set)basePackages).add(ClassUtils.getPackageName(clazz));
            clientClasses.add(clazz.getCanonicalName());
          }
    
          AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
            protected boolean match(ClassMetadata metadata) {
              String cleaned = metadata.getClassName().replaceAll("\$", ".");
              return clientClasses.contains(cleaned);
            }
          };
          scanner.addIncludeFilter(new FeignClientsRegistrar.AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
        } else {
          scanner.addIncludeFilter(annotationTypeFilter);
          basePackages = this.getBasePackages(metadata);
        }
    
        Iterator var17 = ((Set)basePackages).iterator();
    
        while(var17.hasNext()) {
          String basePackage = (String)var17.next();
          Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
          Iterator var21 = candidateComponents.iterator();
    
          while(var21.hasNext()) {
            BeanDefinition candidateComponent = (BeanDefinition)var21.next();
            if (candidateComponent instanceof AnnotatedBeanDefinition) {
              AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition)candidateComponent;
              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 name = this.getClientName(attributes);
              this.registerClientConfiguration(registry, name, attributes.get("configuration"));
              this.registerFeignClient(registry, annotationMetadata, attributes);
            }
          }
        }
    
      }
    
  • 相关阅读:
    AtCoder Grand Contest 033
    Luogu P6620 [省选联考 2020 A 卷] 组合数问题
    Luogu P6631 [ZJOI2020] 序列
    Luogu P6630 [ZJOI2020] 传统艺能
    Luogu P6633 [ZJOI2020] 抽卡
    Luogu P6623 [省选联考 2020 A 卷] 树
    AtCoder Grand Contest 034
    Luogu P5445 [APIO2019] 路灯
    LOJ #6059. 「2017 山东一轮集训 Day1」Sum
    Luogu P3721 [AH2017/HNOI2017]单旋
  • 原文地址:https://www.cnblogs.com/helloz/p/11266358.html
Copyright © 2011-2022 走看看