public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "Bean definition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
        ((AbstractBeanDefinition) beanDefinition).validate();
      } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(
            beanDefinition.getResourceDescription(),
            beanName,
            "Validation of bean definition failed",
            ex);
      }
    }

    Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    if (oldBeanDefinition != null) {
      if (!this.allowBeanDefinitionOverriding) {
        throw new BeanDefinitionStoreException(
            beanDefinition.getResourceDescription(),
            beanName,
            "Cannot register bean definition ["
                + beanDefinition
                + "] for bean '"
                + beanName
                + "': there's already ["
                + oldBeanDefinition
                + "] bound");
      } else {
        if (logger.isInfoEnabled()) {
          logger.info(
              "Overriding bean definition for bean '"
                  + beanName
                  + "': replacing ["
                  + oldBeanDefinition
                  + "] with ["
                  + beanDefinition
                  + "]");
        }
      }
    } else {
      this.beanDefinitionNames.add(beanName);
    }
    this.beanDefinitionMap.put(beanName, beanDefinition);

    // Remove corresponding bean from singleton cache, if any.
    // Shouldn't usually be necessary, rather just meant for overriding
    // a context's default beans (e.g. the default StaticMessageSource
    // in a StaticApplicationContext).
    removeSingleton(beanName);
  }
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactoryToProcess)
      throws BeansException {

    StringValueResolver valueResolver = new BeanDirectoryResolver();

    BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);

    String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
    for (int i = 0; i < beanNames.length; i++) {

      BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]);
      try {
        visitor.visitBeanDefinition(bd);
      } catch (BeanDefinitionStoreException ex) {
        throw new BeanDefinitionStoreException(
            bd.getResourceDescription(), beanNames[i], ex.getMessage());
      }
    }

    // New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
    beanFactoryToProcess.resolveAliases(valueResolver);

    // New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
    beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
  }