spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
55.28k stars 37.62k forks source link

`AnnotationConfigWebApplicationContext` should propagate `ApplicationStartup` to `BeanFactory` #32747

Closed gavlyukovskiy closed 2 weeks ago

gavlyukovskiy commented 2 weeks ago

Affects: 5.3.x, 6.0.x, 6.1.x, 6.2.x


When setting ApplicationStartup on AnnotationConfigWebApplicationContext (or to be precise any AbstractApplicationContext that isn't also GenericApplicationContext) it's not getting propagated to BeanFactory after it was created:

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
FlightRecorderApplicationStartup applicationStartup = new FlightRecorderApplicationStartup();
context.setApplicationStartup(applicationStartup);
context.refresh();
System.out.println(context.getBeanFactory().getApplicationStartup() == applicationStartup); // false

and as a result no bean events are recorded.

It's also not possible to set applicationStartup on the bean factory because it's not created yet, so that results in

BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext

As a workaround we can extend the AnnotationConfigWebApplicationContext and either override createBeanFactory

@Override
protected DefaultListableBeanFactory createBeanFactory() {
    DefaultListableBeanFactory beanFactory = super.createBeanFactory();
    beanFactory.setApplicationStartup(getApplicationStartup());
    return beanFactory;
}

or override customizeBeanFactory that already propagates other context settings to the BeanFactory

@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    super.customizeBeanFactory(beanFactory);
    beanFactory.setApplicationStartup(getApplicationStartup());
}

I think that should be done by default from the framework.

P.S. it doesn't reproduce with spring-boot because it uses different (similar?) context - AnnotationConfigServletWebApplicationContext