Skip to content

Feature: Introduce @RequiredBy annotation for reverse dependency declaration #36521

@TAKETODAY

Description

@TAKETODAY

Background

Spring Framework currently provides @DependsOn to declare that a bean depends on other beans. This is useful when certain beans must be initialized before the annotated bean. However, there is no built‑in way to express the reverse relationship: a bean that is depended upon by other beans and therefore must be initialized before those beans.

In large applications, especially when working with auto‑configured infrastructure beans like DataSource, it is common to need some custom beans (e.g., connection pool decorators, security initializers, logging components) to be fully initialized before the DataSource is created. Currently, achieving this without modifying the auto‑configuration or manually defining the DataSource bean is cumbersome.

Use Case

Consider a Spring Boot application that uses the default DataSourceAutoConfiguration. You have a custom bean MyEarlyBean that must be initialized before the DataSource bean.
With the existing @DependsOn, you would have to:

  1. Exclude DataSourceAutoConfiguration
  2. Define your own DataSource bean and annotate it with @DependsOn("myEarlyBean")

This works, but it forces you to take full control over the DataSource definition, losing the benefits of auto‑configuration. A more declarative, non‑intrusive approach would be desirable.

Proposed API

Introduce a new annotation @RequiredBy that can be placed on a bean class or a @Bean method. It declares that the annotated bean must be initialized before the beans specified by the annotation.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredBy {

    /**
     * Bean names that depend on the annotated bean.
     */
    String[] value() default {};

    /**
     * Bean types that depend on the annotated bean.
     * All beans matching these types will be made to depend on the annotated bean.
     */
    Class<?>[] type() default {};
}

Example Usage

@Component
@RequiredBy(type = DataSource.class)
public class MyEarlyBean {
    // this bean will be initialized before any DataSource bean
}

or with bean name:

@Component
@RequiredBy("dataSource")
public class MyEarlyBean {
    // ...
}

How It Would Work

When the application context is refreshed, a BeanFactoryPostProcessor would scan all bean definitions for the @RequiredBy annotation. For each annotated bean, it would add the bean’s name to the dependsOn set of every target bean specified via value or type. This is essentially the inverse of what @DependsOn does: instead of modifying the annotated bean’s dependencies, it modifies the dependencies of the target beans.

This approach:

  • Works with auto‑configuration (no need to exclude DataSourceAutoConfiguration)
  • Preserves all existing dependency handling logic
  • Can be implemented efficiently using AnnotatedBeanDefinition metadata to avoid class loading where possible

Why This Cannot Be Solved Elegantly by Existing Features

  • @DependsOn requires modifying the bean that should be later (the DataSource) to list its prerequisites. In the case of auto‑configured beans, that would mean either excluding the auto‑configuration and re‑declaring the bean, or using BeanFactoryPostProcessor to programmatically add dependsOn – which is exactly what we want to standardize.
  • @Order / @Priority affect only beans of the same type and are not designed for inter‑bean ordering across arbitrary types.
  • @AutoConfigureBefore / @AutoConfigureAfter work at the auto‑configuration level, not at the individual bean level.

Implementation Sketch

A minimal implementation could be a BeanFactoryPostProcessor similar to:

@Component
public class RequiredByBeanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 1. Find all beans annotated with @RequiredBy
        // 2. For each target bean (by name or type), add the annotated bean to its dependsOn
    }
}

Performance considerations:

  • Use AnnotatedBeanDefinition metadata when available to avoid unnecessary class loading.
  • If performance is a concern, the scanning could be limited to bean definitions that actually need processing.

Alternatives Considered

  • Manual BeanFactoryPostProcessor in user code – possible but requires boilerplate code and is not standardized. Many developers would benefit from a built‑in, well‑tested solution.
  • @DependsOn with auto‑configuration exclusion – works but is invasive and discards auto‑configuration features.
  • ApplicationListener<ContextRefreshedEvent> – runs too late (after all beans are already initialized) and cannot affect initialization order.

Benefits

  • Declarative – clearly expresses “this bean must be ready before that bean”.
  • Non‑intrusive – works with auto‑configuration and third‑party beans.
  • Symmetry with @DependsOn – completes the dependency declaration picture.
  • Reduces boilerplate – no need to write custom BeanFactoryPostProcessor for common ordering needs.

Related Discussions


Next Steps

I would like to open a discussion on whether this feature aligns with Spring’s roadmap. If there is interest, I can prepare a pull request with an implementation, documentation, and tests.

Thank you for considering this feature!

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: waiting-for-triageAn issue we've not yet triaged or decided on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions