@Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
      // 排除内联类
      if (beanDefinition.getMetadata().getClassName().contains("$")) {
        return false;
      }

      // 对于concreteClass,直接返回true
      if (super.isCandidateComponent(beanDefinition)) {
        return true;
      }

      if (!includeAbstractClasses) {
        return false;
      }

      // 非concrete,但指定了includeAbstractClasses=true
      beanDefinition.setBeanClassName(NonInstantiatableClassFactoryBean.class.getName());
      beanDefinition
          .getConstructorArgumentValues()
          .addIndexedArgumentValue(
              0, beanDefinition.getMetadata().getClassName(), Class.class.getName());

      return true;
    }
  @Override
  protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");
    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
    for (String basePackage : basePackages) {
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
      for (BeanDefinition candidate : candidates) {
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
        candidate.setScope(scopeMetadata.getScopeName());
        String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
        if (candidate instanceof AbstractBeanDefinition) {
          postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
        }
        if (candidate instanceof AnnotatedBeanDefinition) {
          processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
        }

        ScannedGenericBeanDefinition bd = (ScannedGenericBeanDefinition) candidate; // 通用bean扫描
        bd.setBeanClassName(HessianServiceExporter.class.getName()); // 设置bean名称
        bd.setBeanClass(HessianServiceExporter.class); // 设置bean类
        bd.getPropertyValues().add("service", registry.getBeanDefinition(beanName)); // 设置属性 service
        String[] interfaces = bd.getMetadata().getInterfaceNames(); // 获得元数据、接口名称

        if (interfaces == null || interfaces.length == 0) continue;
        Class interf = null;
        try {
          interf = Class.forName(interfaces[0]); // 获得接口
        } catch (ClassNotFoundException e) {
          continue;
        }
        bd.getPropertyValues().add("serviceInterface", interf); // 设置属性 serviceInterface
        candidate = bd;
        BeanDefinitionHolder definitionHolder =
            new BeanDefinitionHolder(candidate, "/" + beanName); // 新bean定义持有
        definitionHolder =
            applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 应用范围代理模式
        beanDefinitions.add(definitionHolder); // 将bean定义持有放入bean定义持有set中
        registerBeanDefinition(definitionHolder, this.registry); // 注册bean定义
      }
    }

    if (beanDefinitions.isEmpty()) {
      System.out.println("not service be scaned");
    } else {
      for (BeanDefinitionHolder holder : beanDefinitions) {
        AnnotatedBeanDefinition definition =
            (AnnotatedBeanDefinition) holder.getBeanDefinition(); // 注释的bean定义
        System.out.println("service:" + holder.getBeanName()); // 注释的bean定义名称
        System.out.println(
            "service:" + definition.getMetadata().getAnnotationTypes()); // 注释的bean定义类型
      }
    }

    return beanDefinitions;
  }
 void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
   AnnotationMetadata metadata = abd.getMetadata();
   if (metadata.isAnnotated(Primary.class.getName())) {
     abd.setPrimary(true);
   }
   if (metadata.isAnnotated(Lazy.class.getName())) {
     abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
   }
   if (metadata.isAnnotated(DependsOn.class.getName())) {
     abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));
   }
   if (abd instanceof AbstractBeanDefinition) {
     if (metadata.isAnnotated(Role.class.getName())) {
       Integer role = attributesFor(metadata, Role.class).getNumber("value");
       ((AbstractBeanDefinition) abd).setRole(role);
     }
   }
 }
 /**
  * Derive a bean name from one of the annotations on the class.
  *
  * @param annotatedDef the annotation-aware bean definition
  * @return the bean name, or <code>null</code> if none is found
  */
 protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
   AnnotationMetadata amd = annotatedDef.getMetadata();
   Set<String> types = amd.getAnnotationTypes();
   String beanName = null;
   for (String type : types) {
     Map<String, Object> attributes = amd.getAnnotationAttributes(type);
     if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
       String value = (String) attributes.get("value");
       if (StringUtils.hasLength(value)) {
         if (beanName != null && !value.equals(beanName)) {
           throw new IllegalStateException(
               "Stereotype annotations suggest inconsistent "
                   + "component names: '"
                   + beanName
                   + "' versus '"
                   + value
                   + "'");
         }
         beanName = value;
       }
     }
   }
   return beanName;
 }
 /**
  * Determine whether the given bean definition qualifies as candidate.
  *
  * <p>The default implementation checks whether the class is concrete (i.e. not abstract and not
  * an interface). Can be overridden in subclasses.
  *
  * @param beanDefinition the bean definition to check
  * @return whether the bean definition qualifies as a candidate component
  */
 protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
   return (beanDefinition.getMetadata().isConcrete()
       && beanDefinition.getMetadata().isIndependent());
 }
 public boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
   return super.isCandidateComponent(beanDefinition)
       && beanDefinition.getMetadata().hasAnnotation(CustomizeComponent.class.getName());
 }