Affects: spring-context:5.2.5.RELEASE


I register a new BeanDefinition via context.registerBeanDefinition , but I still have NoSuchBeanDefinitionException on context.getBean because context.getBean cached my previous call before bean registration.

Only if I call context.getBeanFactory().clearMetadataCache() manually this code doesn't throw any exception, but now it does.

import static org.assertj.core.api.Assertions.assertThat;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.support.GenericApplicationContext;

@Slf4j
public class DefaultListableBeanFactoryRedundantCacheTest {

    @Test
    public void noSuchBeanDefinitionExceptionAfterRegisterBean() {
        try (GenericApplicationContext context = new GenericApplicationContext()) {
            context.refresh();
            NoSuchBeanDefinitionException exception = null;
            try {
                context.getBean(Bean.class);
            } catch (NoSuchBeanDefinitionException ex) {
                exception = ex;
                log.error("It's ok. " +
                        "But 'org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType" +
                        "(java.lang.Class<?>, boolean, boolean)' has added bean to cache '#501 - cache.put(type, resolvedBeanNames);'"
                    , ex);
            }
            assertThat(exception).isInstanceOf(NoSuchBeanDefinitionException.class);

            /* No Clear Metadata Cache 'context.getBeanFactory().clearMetadataCache()' */

            final BeanDefinition definition = BeanDefinitionBuilder
                .genericBeanDefinition(Bean.class)
                .getBeanDefinition();
            context.registerBeanDefinition("myBean", definition);

            final Bean newBean = context.getBean(Bean.class);

            assertThat(newBean).isNotNull();
        }
    }
}

I think unsuccessful resolved bean shouldn't be cached in getBeanNamesForType.