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);
        }
      }
    }

  }

转载于:https://www.cnblogs.com/helloz/p/11266358.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值