Affects: 6.1

While looking at the sample for #33180 I noticed several warning messages related to eager injection and bean post-processing:

2024-07-10T09:55:40.473+01:00  WARN 593 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'application.SecurityConfig.OAuthSecurityConfig' of type [org.example.testsb.Application$SecurityConfig$OAuthSecurityConfig$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-10T09:55:40.501+01:00  WARN 593 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'application.PermissionEvaluatorTest' of type [org.example.testsb.Application$PermissionEvaluatorTest] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-10T09:55:40.504+01:00  WARN 593 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'methodSecurityExpressionHandler' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-10T09:55:40.505+01:00  WARN 593 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationManager' of type [org.example.testsb.Application$SecurityConfig$OAuthSecurityConfig$$Lambda$464/0x000000013c380b58] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-10T09:55:40.507+01:00  WARN 593 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationEventPublisher' of type [org.springframework.security.authorization.SpringAuthorizationEventPublisher] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.

Each warning suggests that the declaration of healthEndpointGroupsBeanPostProcessor and its dependencies should be checked, but I don't think it's the culprit. In each case, the stack when the warning is logged is the following:

Thread [main] (Suspended (breakpoint at line 437 in PostProcessorRegistrationDelegate$BeanPostProcessorChecker))    
    owns: ConcurrentHashMap<K,V>  (id=42)   
    PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization(Object, String) line: 437 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyBeanPostProcessorsAfterInitialization(Object, String) line: 438 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1789    
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 600 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 522   
    DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 326  
    0x000000013e1f97e8.getObject() line: not available  
    DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 234   
    DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 324    
    DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 200   
    ConstructorResolver.instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 409   
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 1335   
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 1165  
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 562 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 522   
    DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 326  
    0x000000013e1f97e8.getObject() line: not available  
    DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 234   
    DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 324    
    DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class<T>) line: 205 
    AbstractAdvisorAutoProxyCreator$BeanFactoryAdvisorRetrievalHelperAdapter(BeanFactoryAdvisorRetrievalHelper).findAdvisorBeans() line: 91 
    InfrastructureAdvisorAutoProxyCreator(AbstractAdvisorAutoProxyCreator).findCandidateAdvisors() line: 111    
    InfrastructureAdvisorAutoProxyCreator(AbstractAdvisorAutoProxyCreator).findEligibleAdvisors(Class<?>, String) line: 96  
    InfrastructureAdvisorAutoProxyCreator(AbstractAdvisorAutoProxyCreator).getAdvicesAndAdvisorsForBean(Class<?>, String, TargetSource) line: 78    
    InfrastructureAdvisorAutoProxyCreator(AbstractAutoProxyCreator).wrapIfNecessary(Object, String, Object) line: 368   
    InfrastructureAdvisorAutoProxyCreator(AbstractAutoProxyCreator).postProcessAfterInitialization(Object, String) line: 320    
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyBeanPostProcessorsAfterInitialization(Object, String) line: 438 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1789    
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 600 
    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 522   
    DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 326  
    0x000000013e1f97e8.getObject() line: not available  
    DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 234   
    DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 324    
    DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class<T>) line: 205 
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(ConfigurableListableBeanFactory, AbstractApplicationContext) line: 277 
    AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).registerBeanPostProcessors(ConfigurableListableBeanFactory) line: 805    
    AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 608  
    AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 146  
    SpringApplication.refresh(ConfigurableApplicationContext) line: 754 
    SpringApplication.refreshContext(ConfigurableApplicationContext) line: 456  
    SpringApplication.run(String...) line: 334  
    SpringApplication.run(Class<?>[], String[]) line: 1354  
    SpringApplication.run(Class<?>, String...) line: 1343   
    Application.main(String[]) line: 34 

It's finding eligible advisors that's causing the problem. This is happening through AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String) that's called after healthEndpointGroupsBeanPostProcessor has been created and initialized. The warnings can be reduced by marking the dependencies of the sample's Advisor bean, authorizationManagerBeforeMethodInterception, as @Lazy:

@Bean
@Role(ROLE_INFRASTRUCTURE)
public Advisor authorizationManagerBeforeMethodInterception(@Lazy AuthorizationManager<MethodInvocation> authorizationManager,
                                                            @Lazy AuthorizationEventPublisher publisher) {
    AuthorizationManagerBeforeMethodInterceptor authorizationManagerBeforeMethodInterceptor =
        AuthorizationManagerBeforeMethodInterceptor.preAuthorize(authorizationManager);
    authorizationManagerBeforeMethodInterceptor.setAuthorizationEventPublisher(publisher);

    return authorizationManagerBeforeMethodInterceptor;
}

This reduces the warnings from five to two:

2024-07-10T10:05:55.107+01:00  WARN 3196 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'application.SecurityConfig.OAuthSecurityConfig' of type [org.example.testsb.Application$SecurityConfig$OAuthSecurityConfig$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-07-10T10:05:55.141+01:00  WARN 3196 --- [testSB3.3.1] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationEventPublisher' of type [org.springframework.security.authorization.SpringAuthorizationEventPublisher] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [healthEndpointGroupsBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.

Is it possible to detect the case where Advisor beans are involved and point people in that direction?

Comment From: Paper-Folding

I encountered the same issue only after I have declared a RoleHierarchyImpl bean in my Spring Security Configuration:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
public class SpringSecurityConfiguration {
    // other beans and securityFilterChain....

    @Bean
    public RoleHierarchy roleHierarchy() {
        return RoleHierarchyImpl.fromHierarchy("ROLE_admin > ROLE_user");
    }
}

Almost all beans within IoC container complain about "The bean of type 'xxx' is not eligible for getting processed by all BeanPostProcessors.":

2024-09-02T12:42:47.896+08:00  WARN 18176 --- [demo_application] [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactory' of type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-09-02T12:42:47.900+08:00  WARN 18176 --- [demo_application] [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactory' of type [jdk.proxy4.$Proxy131] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-09-02T12:42:47.917+08:00  WARN 18176 --- [demo_application] [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jpaSharedEM_entityManagerFactory' of type [jdk.proxy4.$Proxy132] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-09-02T12:42:47.933+08:00  WARN 18176 --- [demo_application] [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jpaMappingContext' of type [org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.
2024-09-02T12:42:47.934+08:00  WARN 18176 --- [demo_application] [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jpaMappingContext' of type [org.springframework.data.jpa.mapping.JpaMetamodelMappingContext] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [projectingArgumentResolverBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.

Any idea why the warning is raised?

Comment From: jhoeller

The only proper way out here is a combination @Lazy injection points for advisors and/or @Role(BeanDefinition.ROLE_INFRASTRUCTURE) on the affected beans. Generally it also helps to declare such infrastructure bean methods as static or to decompose them into several configuration classes so that they are not mixed with application beans on the same configuration class instance.

That said, the warning message is incomplete indeed since it's not about injected dependencies but also abouter advisors to apply; I'll refine it for 6.1.14.