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
.