When using Configuration annotation BeanDefinitionRegistryPostProcessor, the instance type of dependency injection is inconsistent with getBeanClassName in BeanDefinition. The code is as follows

@Configuration
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        System.out.println();
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println();
    } 
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DemoApplication.class})
public class DemoApplicationTests {

    @Autowired
    private ConfigurableApplicationContext context;

    @Autowired
    private MyBeanDefinitionRegistryPostProcessor myBeanDefinitionRegistryPostProcessor;

    @Test
    public void beanClassTest() {

        String beanClass = myBeanDefinitionRegistryPostProcessor.getClass().getName();

        String beanDefinitionBeanClass = context.getBeanFactory()
                .getBeanDefinition("myBeanDefinitionRegistryPostProcessor")
                .getBeanClassName();

        System.out.println(beanClass);
        System.out.println(beanDefinitionBeanClass);

        Assert.assertEquals("beanClass should equals beanDefinitionBeanClass", beanClass, beanDefinitionBeanClass);
    }
}

Spring When using Configuration annotation BeanDefinitionRegistryPostProcessor, the instance type of dependency injection is inconsistent with getBeanClassName in BeanDefinition

The reasons are as follows:

The method enhanceConfigurationClasses in org.springframework.context.annotation.ConfigurationClassPostProcessor ,as long as beanDef is a full configuration, it will be added to configBeanDefs and then generated by cglib into the new class, resulting in updating the beanClassName in BeanDefinition. The code should be changed to the following

Spring When using Configuration annotation BeanDefinitionRegistryPostProcessor, the instance type of dependency injection is inconsistent with getBeanClassName in BeanDefinition

Comment From: lgxbslgx

I submit a PR to solve this issue. The PR follows the log that says Cannot enhance @Configuration bean definition since its singleton instance has been created too early.

In my opinion, I think we could enhance it even if it has been created. Maybe we should use the enhanced bean definition to create the new instance and override the old one.

@jhoeller What is your opinion. If you agree with me, I would modify my PR which would create the new instance instead of following the log.

Comment From: brucelwl

I submit a PR to solve this issue. The PR follows the log that says Cannot enhance @Configuration bean definition since its singleton instance has been created too early.

In my opinion, I think we could enhance it even if it has been created. Maybe we should use the enhanced bean definition to create the new instance and override the old one.

@jhoeller What is your opinion. If you agree with me, I would modify my PR which would create the new instance instead of following the log.

@lgxbslgx @jhoeller This is not a good solution because it breaks the Spring bean singleton,because the beans created in advance have been invoked, if replacing the beans causes inconsistencies, I think it's only necessary to enhance the configuration beans that are not instantiated

Comment From: brucelwl

@lgxbslgx
Spring When using Configuration annotation BeanDefinitionRegistryPostProcessor, the instance type of dependency injection is inconsistent with getBeanClassName in BeanDefinition It is suggested that we should change it to this way of writing. ...... else if (beanFactory.containsSingleton(beanName) && 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); } ......

Comment From: lgxbslgx

else if (beanFactory.containsSingleton(beanName) && logger.isInfoEnabled()) {
    logger.info("Cannot enhance @Configuration bean definition '" + beanName .......);
}
else {
    configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}

The code above maybe causes some problem. If beanFactory.containsSingleton(beanName) is true and logger.isInfoEnabled() is false, the configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef) would be executed, which is not our expectation.

Comment From: brucelwl

@lgxbslgx Sorry, you're right.

Comment From: brucelwl

@lgxbslgx @sbrannen @jhoeller This problem has been reported for 9 days. Why not deal with it?

Comment From: lgxbslgx

@sbrannen @jhoeller This problem has been backlogged for a long time. Do you have time to review the PR? Thanks.

Comment From: sbrannen

MyBeanDefinitionRegistryPostProcessor should not be annotated with @Configuration since it is not a Java Config class.

The fact that you have annotated it with @Configuration is why you see $$EnhancerBySpringCGLIB appended to the class name.

How does your application behave if you annotate MyBeanDefinitionRegistryPostProcessor with @Component?

Comment From: brucelwl

@sbrannen Yes, using @Component would be the right performance.

Comment From: sbrannen

@sbrannen Yes, using @component would be the right performance.

Thanks for the feedback, @brucelwl.

Does that mean that we can close this issue as resolved from your end?

Comment From: brucelwl

@sbrannen Yes, using @component would be the right performance.

Thanks for the feedback, @brucelwl.

Does that mean that we can close this issue as resolved from your end?

I just think that if a developer accidentally uses @Configuration, there will be an imperfect warning message or even a bug in this place, because the log says that there is no proxy, but it changes that class is a proxy class. If you think this is an unimportant problem, you can close this issue.

Comment From: sbrannen

Thanks for the additional input, @brucelwl.

We'll consider whether it makes sense to provide additional diagnostic information for such use cases.