From 882d95feb818601cd5e5373546dfb4c14a087d44 Mon Sep 17 00:00:00 2001 From: liguoxiong Date: Sat, 18 May 2019 22:53:34 +0800 Subject: [PATCH] Cannot enhance @Configuration bean definition Cannot enhance @Configuration bean definition if its singleton instance has been created too early. Add the corresponding testcase. See #22990. --- .../ConfigurationClassPostProcessor.java | 16 +++++---- .../ConfigurationClassPostProcessorTests.java | 34 ++++++++++++++++--- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 4baaa4f94da..6afa3ace649 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -405,13 +405,17 @@ public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFact throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } - else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { - logger.info("Cannot enhance @Configuration bean definition '" + beanName + - "' since its singleton instance has been created too early. The typical cause " + - "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + - "return type: Consider declaring such methods as 'static'."); + else if (beanFactory.containsSingleton(beanName)) { + if (logger.isInfoEnabled()) { + logger.info("Cannot enhance @Configuration bean definition '" + beanName + + "' since its singleton instance has been created too early. The typical cause " + + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + + "return type: Consider declaring such methods as 'static'."); + } + } + else { + configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } - configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 61a30352fa7..b816f270a58 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -34,11 +34,8 @@ import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.DefaultPointcutAdvisor; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanDefinitionStoreException; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; import org.springframework.beans.factory.annotation.Lookup; @@ -1118,6 +1115,16 @@ public void testBeanDefinitionRegistryPostProcessorConfig() { assertTrue(ctx.getBean("myTestBean") instanceof TestBean); } + @Test + public void testBeanDefinitionRegistryPostProcessorImplementation() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(PostProcessorConfiguration.class); + ConfigurableListableBeanFactory testBeanFactory = ctx.getBeanFactory(); + PostProcessorConfigurationUser user = (PostProcessorConfigurationUser) ctx.getBean("postProcessorConfigurationUser"); + assertEquals(user.getClass().getName(), + testBeanFactory.getBeanDefinition("postProcessorConfigurationUser").getBeanClassName()); + assertEquals(user.postProcessorConfiguration.getClass().getName(), + testBeanFactory.getBeanDefinition("configurationClassPostProcessorTests.PostProcessorConfiguration").getBeanClassName()); + } // ------------------------------------------------------------------------- @@ -2005,4 +2012,21 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) } } + @Configuration + static class PostProcessorConfiguration implements BeanDefinitionRegistryPostProcessor { + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + registry.registerBeanDefinition("postProcessorConfigurationUser", new RootBeanDefinition(PostProcessorConfigurationUser.class)); + } + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + } + } + + static class PostProcessorConfigurationUser { + @Autowired + PostProcessorConfiguration postProcessorConfiguration; + + } + }