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

Warning message about bean post-processing and eager injection may suggest the wrong cause #33184

Closed
wilkinsona opened this issue Jul 10, 2024 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@wilkinsona
Copy link
Member

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?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 10, 2024
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Jul 10, 2024
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jul 29, 2024
@jhoeller jhoeller added this to the 6.2.x milestone Jul 29, 2024
@jhoeller jhoeller self-assigned this Jul 29, 2024
@Paper-Folding
Copy link

Paper-Folding commented Sep 2, 2024

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?

@jhoeller jhoeller modified the milestones: 6.2.x, 6.1.14 Sep 27, 2024
@jhoeller
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants