Description
Hannes Schmidt opened SPR-8941 and commented
I have two beans A and B. Both are services, both implement SmartLifecycle. Both have an auto-wired dependency to the other bean. IOW, there is a circular dependency between them. A.getPhase() returns 1, B.getPhase() returns 2. Intuitively, the expected behavior is that A.start() is invoked before B.start(). The actual behavior in 3.0.5 is that B.start() is invoked before A.start().
DefaultLifecycleProcessor attempts to start A first, but before doing so starts all lifecycle beans among A's dependencies first. B is one of those so its start() is actually invoked first.
My take on this is that an injection dependency is not necessarily the same as a lifecycle dependency. Spring's lifecycle processing treats them as the same thing. Bean X may depend on bean Y and yet bean X might have to be started before Y for reasons orthogonal to dependency injection, say concurrency. SmartLifecycle's Javadocs state explicitly that depends-on has priority over phases, yet I feel that overriding getPhase() is a much stronger statement than introducing a bean reference, especially when it is auto-wired, so I would think that getPhase() should overrule depends-on relationships.
I don't see how these two dependency sets can be untangled without breaking backwards compatibility.
On the other hand, we could limit the fix to circularly dependent beans: If beans A and B depend on each other but belong to distinct phases, the dependency should be ignored. I'd be willing to supply a patch, if requested.
Affects: 3.0.5
1 votes, 1 watchers