They're registered as beans in the child context through ServletWebServerFactoryAutoConfiguration
which is registered with the child context by the ManagementContextFactory
:
https://github.com/spring-projects/spring-boot/blob/1e73a7cf8b376ea4b5ead9e56df093e5354c4de7/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextAutoConfiguration.java#L49-L53
They're then called by WebServerFactoryCustomizerBeanPostProcessor
.
They're called a second time through ServletManagementWebServerFactoryCustomizer
. It's configured with a variety of customizer classes:
https://github.com/spring-projects/spring-boot/blob/1e73a7cf8b376ea4b5ead9e56df093e5354c4de7/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfiguration.java#L127-L132
Beans of these types are then retrieved from the context and called:
https://github.com/spring-projects/spring-boot/blob/1e73a7cf8b376ea4b5ead9e56df093e5354c4de7/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java#L77-L88
As far as I can tell, we only need one of these two mechanisms. If we got rid of the second, it would address #44068 at the same time.
There's a similar arrangement on the reactive side with ReactiveWebServerFactoryAutoConfiguration
and ReactiveManagementWebServerFactoryCustomizer
that results in the same double customization.