Based on the following pseudo-code
Spring does NOT auto-start a solo Lifecycle
bean:
@Component public class ManualService implements Lifecycle {}
Spring auto-starts any Lifecycle
bean that is dependent of a SmartLifecycle
:
@Component public class ManualService implements Lifecycle {}
@Component public class AutoService implements SmartLifecycle {
@Autowired private ManualService dependent;
public boolean isAutoStartup() { return true; }
}
Here is where I got confused. Spring auto-starts a Lifecycle
bean even though, a few lines later, it determines it is not required:
@SpringBootApplication
public class Issue31337 {
public static void main(String[] args) { SpringApplication.run(Issue31337.class, args); }
@Component public static class ManualService implements Lifecycle {
private boolean running;
public void start() { running = true; System.out.println(this.getClass().getSimpleName()); }
public void stop() { running = false; }
public boolean isRunning() { return running; }
}
@Component public static class AutoService extends ManualService implements SmartLifecycle {
@Autowired private ManualService dependent;
public boolean isAutoStartup() { return false; }
}
}
This means the mere presence of the SmartLifecycle
bean in the context triggers all of stuff to occur. This is made all the harder to follow by #15122 which describes how a transitive Lifecycle
bean is not started.
Now the behaviour is arguable both ways but surely autoStartup=false says "Leave me alone, I've got this". In my case, the AutoService start()
explicitly calls dependent.start()
so my workaround is to stop using Lifecycle
to represent anything manually startable.
Affects: spring-context 5.3.28
Comment From: snicoll
@drekbour I didn't get what's confusing. The Javadoc of Lifecycle
and SmartLifecycle
clearly explains the difference between the two.
Note that the present Lifecycle interface is only supported on top-level singleton beans. On any other component, the Lifecycle interface will remain undetected and hence ignored. Also, note that the extended SmartLifecycle interface provides sophisticated integration with the application context's startup and shutdown phases.
but surely autoStartup=false says "Leave me alone, I've got this
If you call start
yourself, I have no idea what you're expecting. It should start the component, the autoStartup bit is about doing this for you.
I am willing to give it another try, but not based on pseudo code. If you believe something is still wrong after having reviewed the javadoc of both classes, please share a small sample that reproduces only the confusing case you've tried to describe. You can do that by attaching a zip to this issue or pushing the code to another GitHub repository.
Comment From: drekbour
If you call start yourself, I have no idea what you're expecting
Nor should you - I got this.
the autoStartup bit is about doing this for you.
But autoStartup is false so AutoService
is not started by Spring but before it checks autoStartup and decides to skip it, DefaultLifecycleProcessor
has already called start()
on all of its Lifecycle
dependencies. They did not need to be started.
not based on pseudo code
I have no IDE available (if such a thing can be true once onto the internet!) so edited the example freehand into something that should compile.
Comment From: snicoll
Cool. But we need a sample we can run ourselves. Not text in code that we’ll have to copy and miss a step you didn’t provide.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.