Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc: Lifecycle (not SmartLifecycle) beans not started at refresh() time [SPR-12855] #17453

Closed
spring-issuemaster opened this issue Mar 26, 2015 · 3 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Mar 26, 2015

Edward Sargisson opened SPR-12855 and commented

The docs say that a top-level bean may implement Lifecycle and have its start method called at startup.

Using such a bean with XmlWebApplicationContext does not have its start method called. Only a bean that implements SmartLifecycle does.

The defects appears to be that FrameworkServlet.configureAndRefreshWebApplicationContext only calls refresh on the web application context. It only ever calls refresh(). This means that the DefaultLifecycleProcessor ends up calling startBeans(autoStartupOnly=true).

In startBeans the following check means that only SmartLifecycle beans are added to the phases collection (and then started).
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup()))

I found this in 4.0.5 but a check of the source on github suggests it's still there.

If there are other code paths that result in DefaultLifecycleProcessor.start() being called I couldn't find them.

Workaround

Implement SmartLifecycle instead of Lifecycle.


Affects: 3.2.13, 4.0.5

Backported to: 3.2.14

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 27, 2015

Juergen Hoeller commented

This is in fact as designed: Regular Lifecycle beans do get ConfigurableApplicationContext.start() calls propagated but are not auto-started by ConfigurableApplicationContext.refresh(). Just SmartLifecycle beans are able to indicate such an auto-startup and are also able to influence the startup order through their phase.

In other words, for regular Lifecycle beans, an ApplicationContext just acts as a propagator of explicit start/stop calls but doesn't do any special treatment beyond that.

All of that said, the documentation isn't as clear as it should be here, so I'll turn this into a documentation task. Thanks for raising this!

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 27, 2015

Edward Sargisson commented

Juergen: Thanks for looking at this.
Part of my point was that when I went tracking back through the source to see what I was missing I couldn't find a .start() call for the code path. I could only find refresh().
This might have been because the Eclipse Search References got confused so perhaps you could point out the code path it's supposed to use when starting a webapp?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 30, 2015

Juergen Hoeller commented

There are two distinct code paths through DefaultLifecycleProcessor: in the refresh phase, handling auto-startups; and through its own implementation of the Lifecycle interface, propagating the start/stop/restart calls to all lifecycle beans. The latter is typically triggered through AbstractApplicationContext's implementation of the Lifecycle interface, for programmatic starting/stopping of the entire context.

Hope that helps,

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.