protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String beanName) {
    if (!this.registry.containsBeanDefinition(beanName)) {
      return false;
    }
    BeanDefinition existingBeanDef = this.registry.getBeanDefinition(beanName);

    // Is the existing bean definition one that was created from a configuration class?
    // -> allow the current bean method to override, since both are at second-pass level.
    // However, if the bean method is an overloaded case on the same configuration class,
    // preserve the existing bean definition.
    if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
      ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
      return (ccbd.getMetadata()
          .getClassName()
          .equals(beanMethod.getConfigurationClass().getMetadata().getClassName()));
    }

    // A bean definition resulting from a component scan can be silently overridden
    // by an @Bean method, as of 4.2...
    if (existingBeanDef instanceof ScannedGenericBeanDefinition) {
      return false;
    }

    // Has the existing bean definition bean marked as a framework-generated bean?
    // -> allow the current bean method to override it, since it is application-level
    if (existingBeanDef.getRole() > BeanDefinition.ROLE_APPLICATION) {
      return false;
    }

    // At this point, it's a top-level override (probably XML), just having been parsed
    // before configuration class processing kicks in...
    if (this.registry instanceof DefaultListableBeanFactory
        && !((DefaultListableBeanFactory) this.registry).isAllowBeanDefinitionOverriding()) {
      throw new BeanDefinitionStoreException(
          beanMethod.getConfigurationClass().getResource().getDescription(),
          beanName,
          "@Bean definition illegally overridden by existing bean definition: " + existingBeanDef);
    }
    if (logger.isInfoEnabled()) {
      logger.info(
          String.format(
              "Skipping bean definition for %s: a definition for bean '%s' "
                  + "already exists. This top-level bean definition is considered as an override.",
              beanMethod, beanName));
    }
    return true;
  }
 /**
  * 获取指定前缀的方法.
  *
  * @param field
  * @param targetCalss
  * @param method
  * @return
  * @throws NoSuchMethodException
  * @throws SecurityException
  */
 @SuppressWarnings("rawtypes")
 public static Method getMethod(
     Field field, Class<?> targetCalss, BeanMethod method, Class[] params)
     throws NoSuchMethodException, SecurityException {
   String fieldname = field.getName();
   StringBuffer methodName = new StringBuffer(method.toString());
   methodName.append(fieldname.substring(0, 1).toUpperCase());
   methodName.append(fieldname.substring(1));
   return targetCalss.getMethod(methodName.toString(), params);
 }
  /**
   * Read the given {@link BeanMethod}, registering bean definitions with the BeanDefinitionRegistry
   * based on its contents.
   */
  private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
    ConfigurationClass configClass = beanMethod.getConfigurationClass();
    MethodMetadata metadata = beanMethod.getMetadata();
    String methodName = metadata.getMethodName();

    // Do we need to mark the bean as skipped by its condition?
    if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
      configClass.skippedBeanMethods.add(methodName);
      return;
    }
    if (configClass.skippedBeanMethods.contains(methodName)) {
      return;
    }

    // Consider name and any aliases
    AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
    List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
    String beanName = (names.size() > 0 ? names.remove(0) : methodName);

    // Register aliases even when overridden
    for (String alias : names) {
      this.registry.registerAlias(beanName, alias);
    }

    // Has this effectively been overridden before (e.g. via XML)?
    if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
      return;
    }

    ConfigurationClassBeanDefinition beanDef =
        new ConfigurationClassBeanDefinition(configClass, metadata);
    beanDef.setResource(configClass.getResource());
    beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

    if (metadata.isStatic()) {
      // static @Bean method
      beanDef.setBeanClassName(configClass.getMetadata().getClassName());
      beanDef.setFactoryMethodName(methodName);
    } else {
      // instance @Bean method
      beanDef.setFactoryBeanName(configClass.getBeanName());
      beanDef.setUniqueFactoryMethodName(methodName);
    }
    beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
    beanDef.setAttribute(
        RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

    AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);

    Autowire autowire = bean.getEnum("autowire");
    if (autowire.isAutowire()) {
      beanDef.setAutowireMode(autowire.value());
    }

    String initMethodName = bean.getString("initMethod");
    if (StringUtils.hasText(initMethodName)) {
      beanDef.setInitMethodName(initMethodName);
    }

    String destroyMethodName = bean.getString("destroyMethod");
    if (destroyMethodName != null) {
      beanDef.setDestroyMethodName(destroyMethodName);
    }

    // Consider scoping
    ScopedProxyMode proxyMode = ScopedProxyMode.NO;
    // TODO Determine why type is hard coded to org.springframework.context.annotation.Scope,
    // since AnnotationScopeMetadataResolver supports a custom scope annotation type.
    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
    if (attributes != null) {
      beanDef.setScope(
          attributes.getAliasedString("value", Scope.class, configClass.getResource()));
      proxyMode = attributes.getEnum("proxyMode");
      if (proxyMode == ScopedProxyMode.DEFAULT) {
        proxyMode = ScopedProxyMode.NO;
      }
    }

    // Replace the original bean definition with the target one, if necessary
    BeanDefinition beanDefToRegister = beanDef;
    if (proxyMode != ScopedProxyMode.NO) {
      BeanDefinitionHolder proxyDef =
          ScopedProxyCreator.createScopedProxy(
              new BeanDefinitionHolder(beanDef, beanName),
              this.registry,
              proxyMode == ScopedProxyMode.TARGET_CLASS);
      beanDefToRegister =
          new ConfigurationClassBeanDefinition(
              (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
    }

    if (logger.isDebugEnabled()) {
      logger.debug(
          String.format(
              "Registering bean definition for @Bean method %s.%s()",
              configClass.getMetadata().getClassName(), beanName));
    }

    this.registry.registerBeanDefinition(beanName, beanDefToRegister);
  }