org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata puts metadata into the org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#injectionMetadataCache, but nothing ever cleans it, leading to a memory leak in case bean definitions for beans with different names get added and removed. This is particularly visible when using Spring Integration's dynamic flows.
This is currently by design: We always retain the latest metadata per bean name, so we effectively clear it for a replaced bean... but not for an individually removed bean since we expect a follow-up instance to appear for the same bean name.
So in your scenario, you see lots of bean definitions added and removed with different names, and autowiring metadata kept around for bean names which are not in use at all anymore? That's quite unusual from the core container perspective. We'd have to introduce a BeanPostProcessor callback for individual removal of bean definitions by name here, clearing the injection and lifecycle caches for it in various post-processor implementations. Alternatively, we could also simply clear all such caches on bean definition removal.
Yeah, I suppose the scenario is somewhat unorthodox in a generic Spring application - however, I'm using Spring Integration's dynamic flows that get started and stopped every day, and quite a few of them, so the cache builds up and overflows pretty quickly. By the way, #21664 is pretty much the same issue, just a different BeanPostProcessor.
I've introduced a resetBeanDefinition(beanName) notification on MergedBeanDefinitionPostProcessor, applying to Autowired as well as Common and PersistenceAnnotationBeanPostProcessor, allowing them to reset their internal caches accordingly. We're triggering this both on replacing and removing a bean definition since it is sensible to immediately clear the caches in both cases, even if it would implicitly happen later on for the replace case anyway.