This is a new feature request to add a new annotation (and capability) to the core Spring Framework that has the opposite effect of the @DependsOn annotation (Javadoc).

With Spring's @DependsOn annotation users can say bean B depends on bean A, like so:

@Configuration
class MyApplicationConfiguration {

  @Bean("B")
  @DependsOn("A")
  B bBean() {
    return new B();
  }

  @Bean("A")
  A aBean(..) {
    return new A();
  }
}

The new, inverse annotation, which I have dubbed @DependencyOf, exists in the Spring Test for Apache Geode (STDG) project; see here.

The equivalent effect using @DependencyOf is the following configuration:

@Configuration
class MyApplicationConfiguration {

  @Bean("A")
  @DependencyOf("B")
  A aBean(..) {
    return new A();
  }

  @Bean("B")
  B bBean() {
    return new B();
  }
}

While this is not very useful in this particular configuration arrangement, it is merely to demonstrate the effect. So, when would @DependencyOf be useful?

The need for this new @DependencyOf annotation came about in testing.

I use the STDG project to consistently and reliably test across Spring Data for Apache Geode (SDG), Spring Session for Apache Geode (SSDG) and Spring Boot for Apache Geode (SBDG). In certain [test] cases, I need beans / components from SDG, SSDG or SBDG to depend on STDG components for testing purposes. Clearly SDG, SSDG and SBDG production components cannot be made to "depend on" STDG test components only used during test runtime.

You can see an example of the @DependencyOf annotation in action in this STDG test class. In a nutshell, a TestCacheLifecycleListener component and bean is a "dependency of" the "gemfireCache" bean which is created in SDG by the declaration of the ClientCacheApplication annotation in the configuration (here).

NOTE: The SDG @ClientCacheApplication annotation responsible for creating a GemFireCache bean is also meta-annotated with Spring's @Configuration annotation making the TestConfiguration class a proper Spring JavaConfig class.

Of course, 1 way this might be accomplished is by having STDG components implement the [Smart]Lifecycle interface. However, this is problematic for 2 reasons 1) SDG, SSDG or SBDG also has SmartLifecycle implementations with a potentially higher precedence and 2) the precedence of SmartLifecycle components in SDG, SSDG and SBDG could change in the future and become higher. There are other situations to consider.

There are of course hooks in the Spring TestContext framework where it might be possible to perform certain initialization in TestExecutionListeners and what not. I have considered multiple angles here.

Yet another implementation would be to use a BeanFactoryPostProcessor to change the dependencies of the SDG, SSDG and SBDG bean definitions.

And, in fact, this is exactly how the @DependencyOf annotation configuration is implemented, by using a BeanFactoryPostProcessor to modify the (would be) dependent beans / components from upstream frameworks. See here.

The @DependencyOf annotation is flexible and easy to add to any (downstream) project that might require beans to get initialized before the upstream framework initializes certain beans.

I am proposing this additional, complimentary annotation as an addition to the core Spring Framework if the team feels this would have value (merit) beyond the use cases I identified. I would be happy to work with interested parties on its integration as needed.

Comment From: funky-eyes

I believe it would bea great convenience to have this feature in place when we sometimes get frustrated with not being able to control the loading order of beans in other components

Comment From: jhoeller

After a team discussion this morning, while we do understand the intention here, we have no plans to introduce such an inverse dependency annotation as a common first-class concept. Any such bean relationships can be programmatically expressed via ConfigurableBeanFactory.registerDependentBean (e.g. in a BeanFactoryPostProcessor as suggested above) already, in a separate piece of logic that understands the overall relationships in a given application context setup.

Conceptually, an annotation that introduces an understanding of a higher-level bean in a lower-level bean definition seems a bit backwards. In the example above, bean A should arguably not be aware of bean B, not even through metadata on its bean definition. It seems cleaner to put such dependency registrations in a separate place that conceptually knows about A as well as B. In particular for production setups, we prefer to strongly suggest such conceptual alignment.

For test setups, there is nothing wrong with declaring extra dependency declarations if needed, on inferring them from the overall setup (or even from annotation declarations) in a BeanFactoryPostProcessor - ideally via ConfigurableBeanFactory.registerDependentBean rather than BeanDefinition.setDependsOn, keeping the dependency declarations separate. We don't really see preferred use cases beyond such scenarios.

Thanks for raising the topic, in any case!

Comment From: agoston

@jxblum can you extract that specific @DependencyOf from the library you referenced? I think I speak for many who would really need this during testing.

Comment From: jxblum

Hi @agoston - Thank you for your continued interests in this feature. I am planning to break this out into a separate library along with many other Spring Framework (and other Spring project, e.g. Spring Boot) extensions I have developed in my specific Spring projects over the years. I have no planned timeframe yet for doing so.

I will give this more thought and post back here soon when I have some concrete details.