You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring依赖其他Bean列表的Bean创建机制解析及规范问询

How Spring Resolves List Dependencies When Creating Beans

Great question! Let’s walk through exactly how Spring handles the scenario where a bean depends on a list of other beans, including the core mechanics and what the Spring specification defines.

Core Mechanism: Autowiring Collection Types

At its core, this is part of Spring’s Dependency Injection (DI) autowiring logic specifically tailored for collection types. Here’s the step-by-step breakdown for your code example:

1. Candidate Bean Discovery

First, Spring scans your application context for all beans that match the generic type of the collection parameter. In your case:

  • TestImpl1 and TestImpl2 are annotated with @Service, so Spring automatically registers them as beans in the context.
  • Both classes implement the Test interface, so they qualify as matching candidates for the List<Test> parameter in your testContainer bean factory method.

2. Spring Specification Definition

The behavior is clearly defined in the Spring Core Specification, which states:

When a bean constructor, factory method, or @Autowired method/parameter requires a collection type (such as List, Set, or Map), Spring automatically collects all bean instances that match the collection's element type and injects them into the collection.

For ordered collections like List, the order of elements follows:

  1. The @Order annotation value (lower values first) or the Ordered interface implementation of the beans.
  2. If no ordering is specified, the order in which beans were registered in the application context.

Generic type parameters are used to narrow down candidates—Spring will only include beans that are compatible with the generic type of the collection.

3. Applying This to Your Code

When Spring creates the testContainer bean:

  1. It first resolves the List<Test> parameter by gathering all Test-type beans (TestImpl1 and TestImpl2) from the context.
  2. This list is passed into your factory method, where you iterate over it to populate the TestContainer's internal list.

A More Concise Alternative

You can simplify your code to align with Spring’s best practices. Instead of manually adding each test bean, use constructor injection directly in TestContainer:

public class TestContainer {
    private final List<Test> testList;

    // Constructor injection (preferred over field injection or manual addition)
    public TestContainer(List<Test> testList) {
        this.testList = new ArrayList<>(testList);
    }
}

Then your bean factory method becomes much cleaner:

@Bean
public TestContainer testContainer(List<Test> testList) {
    return new TestContainer(testList);
}

Extra Details: Ordering and Filtering

  • Controlling List Order: If you want TestImpl1 to appear before TestImpl2 in the list, add the @Order annotation to the service classes:
    @Service
    @Order(1)
    public class TestImpl1 implements Test { }
    
    @Service
    @Order(2)
    public class TestImpl2 implements Test { }
    
  • Filtering Beans: If you only want to include specific Test beans, use the @Qualifier annotation alongside the collection parameter. For example, to only inject beans with the qualifier "specialTest":
    @Bean
    public TestContainer testContainer(@Qualifier("specialTest") List<Test> testList) {
        return new TestContainer(testList);
    }
    
    Don’t forget to add @Qualifier("specialTest") to the relevant Test implementation classes.

内容的提问来源于stack exchange,提问作者Suttonese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 13:53:11