Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid WARN when returning a BeanDefinitionRegistryPostProcessor from within a @Configuration class [SPR-14603] #19172

Closed
spring-issuemaster opened this Issue Aug 18, 2016 · 4 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Aug 18, 2016

Les Hazlewood opened SPR-14603 and commented

Consider the following configuration class:

import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public static BeanDefinitionRegistryPostProcessor myPostProcessor() {
        return new MyBeanDefinitionPostProcessor();
    }
}

(if it matters, this class is loaded in Spring MVC and Spring Boot applications via an @Import(MyConfiguration.class) annotation.)

This causes a WARN message to be printed as follows:

Cannot enhance @Configuration bean definition 'myPostProcessor' 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'.

As you can see, the method is declared as static, yet I still receive the WARN message. When I remove the static modifier, I still receive the same WARN message. Something is amiss.

This is a problem for us because we use this code in a Spring library as well as a Spring Boot starter/plugin that we distribute to customers - when they see the WARN message, they think something is wrong, even though everything is working as expected.


Issue Links:

  • #15258 Allow BeanDefinitionRegistryPostProcessor to register other BeanDefinitionRegistryPostProcessors
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Aug 18, 2016

Les Hazlewood commented

I commented out the @Import approach and tried as a nested static class to see if that would help:

//@Import(MyConfiguration.class)
@Configuration
public class SomeConfiguration {

    @Configuration
    public static class MyConfiguration {
        @Bean
        public static BeanDefinitionRegistryPostProcessor myPostProcessor() {
            return new MyBeanDefinitionPostProcessor();
        }
    }

    //other non-relevant @Bean definitions here...
}

This didn't work either - same WARN message.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Aug 19, 2016

Juergen Hoeller commented

What does your post-processor implementation class look like? The warn message suggests that the post-processor class itself is marked with @Configuration...

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 31, 2017

Thomas Vahrst commented

I get the same warning, when I try to define a BeanDefinitionRegistryPostProcessor as static @Bean method. It seems, thas every BeanDefinition of static defined Beans gets an BeanDefinition attribute org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass = full, because

in ConfigClassBeanDefinitionReader :

	private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
..
		if (metadata.isStatic()) {
			// static @Bean method
			beanDef.setBeanClassName(configClass.getMetadata().getClassName());
			beanDef.setFactoryMethodName(methodName);
		}
		else {

The beanClassName in the beandefinition is set to configClass' classname

and later in ConfigurationClassUtils:

	public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

...
		if (isFullConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}

This seems not to be problem for 'normal' beans, but if the bean type is BeanDefinitionRegistryFactoryPostProcessor, it is instantiated very early. This in turn leads to the warning in ConfigurationClassPostProcessor.enhanceConfigurationClasses becauce both conditions

  • .isFullConfigurationClass AND
  • beanFactory.containsSinglenton
    are true.
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 31, 2017

Thomas Vahrst commented

Our workaround:
put the BeanDefinitionPostProcessor class in a special sub-package, annotate it with @Component und define @ComponentScan(basePackages=...) in the config class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.