spring-projects / spring-projects/spring-framework

Detecting transitive bean dependency usage

Open
#36,153 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core status: waiting-for-triage
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Hi Spring Team,

I work in a large monorepo containing multiple modules maintained by different teams exposing different interfaces. A module is a @Configuration class that creates beans implementing a common interface which is typically configured through properties or the environment the consuming application is running in.

One issue we have with this is managing dependences; imagine something like the following:

class Beans {
@Configuration
  @Import({
      B.class,
      D.class
  })
  public static class A {
    @Bean(name="aBean")
    public Object aBean(
        @Named("bBean") String bBean,
        @Named("cBean") String cBean,
        @Named("dBean") String dBean
    ) {
      return "ABean" + bBean + cBean + dBean;
    }
  }

  @Configuration
  @Import({C.class})
  public static class B {
    @Bean(name="bBean")
    public Object bBean() {
      return "BBean";
    }
  }

  @Configuration
  public static class C {
    @Bean(name="cBean")
    public Object cBean() {
      return "CBean";
    }
  }

  @Configuration
  public static class D {
    @Bean(name="dBean")
    public Object dBean() {
      return "DBean";
    }
  }
}

In this example aBean depends upon bBean, cBean and dBean but its parent @Configuration only imports bBean and dBean directly - cBean is imported transitively via the B module.

To make this easier to maintain (at least in our case) it'd be better if A pulled in C directly via @Import.

I'd like to build a helper library to detect this when the configuration is loaded and if transitive dependencies are detected the library could throw an exception or log a warning message.

Looking through the code that loads @Configuration classes directly this isn't particularly easy; I can pull registered bean definitions out of my DefaultListableBeanFactory after they're registered but I have to do a bunch of work to figure out where they and their dependencies came from. There's the ConfigurationClassPostProcessor/ConfigurationClassParser pair, but the former does all its work in processConfigBeanDefinitions and there's not a good way to observe the ConfigurationClass instances as they're parsed.

Do you have any recommendations on how to proceed here? I'm doing all of this work in spring 6.2.15 - if there are better interfaces in newer versions of the spring framework I can take a look.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ConfigurationClassPostProcessor.processConfigBeanDefinitions and ConfigurationClassParser, which the issue identifies as the configuration-loading path. Trace how ConfigurationClass instances and bean definitions are created, then determine whether a supported observation point can expose transitive imports and bean dependencies. Done means the proposed helper can reliably detect the transitive dependency in the A/B/C/D example without requiring extensive post-processing of DefaultListableBeanFactory data.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.