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