The invocation of MergedBeanDefinitionPostProcessor instances is currently happening has part of bean instantiation https://github.com/spring-projects/spring-framework/blob/ae6a464a80507c63a84cc86c4e711107b097e168/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L574-L586:

For AOT, we need to invoke these upfront so that the bean definition has all the information that we need. We're now in a situation where we need to be able to instantiate certain beans at build-time. This actually requires to register certain core BeanPostProcessors, see https://github.com/spring-projects/spring-framework/issues/28777. With the current arrangement, MergedBeanDefinitionPostProcessor instances registered in the context would be called twice. Once during AOT refresh phase, and once again for the bean that should be instantiated at build-time.

This issue is about finding an API arrangement where this can be streamlined so that it only happen once.

Comment From: snicoll

@jhoeller and I brainstormed and it's not easy as we have several conflicting requirements.

The AOT code needs to browse RootBeanDefinitions including inner bean definitions https://github.com/spring-projects/spring-framework/blob/ae6a464a80507c63a84cc86c4e711107b097e168/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java#L434 whereas the "regular" code does it on the actual bean that is about to be instantiated.

Given that we want to invoke this once, it is hard to define a "key" that would clarify that it is invoked only once as the RootBeanDefinition and the list of MergedBeanDefinitionPostProcessor implementations are not linked.

Comment From: snicoll

It isn't easy to implement. We've gone through a few rounds and the summary is that the context will clone RootBeanDefinition quite a lot. The clone method does not transmit the postProcessed flag so even if we set it upfront, it is lost later on.

The reason why we clone is that creating a bean leads to a call to markBeanAsCreated. If this is the first time the bean is created, its merged bean definition is marked as stale, which leads to invoking the MBDPP again.

After a brainstorming with @jhoeller we're repurposing this issue to review the whole mechanism and see if there isn't a way to avoid re-merging RBD.

Comment From: snicoll

@jhoeller a concrete use case with a test that's failing is available in https://github.com/snicoll/spring-framework/commit/383aba7cbd1708af9102cd88897110e5025b2bac