0
0
SpringbootHow-ToBeginner · 4 min read

How to Inject Multiple Beans in Spring Boot Easily

In Spring Boot, you can inject multiple beans of the same type by using @Autowired with a List or Map of that bean type. Spring will automatically collect all beans of that type and inject them into your component.
📐

Syntax

Use @Autowired on a constructor, field, or setter with a List<BeanType> or Map<String, BeanType>. Spring injects all beans of that type into the collection.

  • List<BeanType>: Injects beans in order of registration.
  • Map<String, BeanType>: Injects beans with their bean names as keys.
java
public class MyService {

    private final List<MyBean> beansList;
    private final Map<String, MyBean> beansMap;

    @Autowired
    public MyService(List<MyBean> beansList, Map<String, MyBean> beansMap) {
        this.beansList = beansList;
        this.beansMap = beansMap;
    }

    // Use beansList or beansMap as needed
}
💻

Example

This example shows two beans implementing the same interface injected as a list and a map into a service. The service prints the beans' names and outputs their behavior.

java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@SpringBootApplication
public class MultipleBeansApp implements CommandLineRunner {

    private final MyService myService;

    @Autowired
    public MultipleBeansApp(MyService myService) {
        this.myService = myService;
    }

    public static void main(String[] args) {
        SpringApplication.run(MultipleBeansApp.class, args);
    }

    @Override
    public void run(String... args) {
        myService.printBeans();
    }
}

interface MyBean {
    String getName();
    String action();
}

@Component("beanOne")
class BeanOne implements MyBean {
    public String getName() { return "BeanOne"; }
    public String action() { return "Action from BeanOne"; }
}

@Component("beanTwo")
class BeanTwo implements MyBean {
    public String getName() { return "BeanTwo"; }
    public String action() { return "Action from BeanTwo"; }
}

@Service
class MyService {
    private final List<MyBean> beansList;
    private final Map<String, MyBean> beansMap;

    @Autowired
    public MyService(List<MyBean> beansList, Map<String, MyBean> beansMap) {
        this.beansList = beansList;
        this.beansMap = beansMap;
    }

    public void printBeans() {
        System.out.println("Beans in List:");
        for (MyBean bean : beansList) {
            System.out.println(bean.getName() + ": " + bean.action());
        }

        System.out.println("\nBeans in Map:");
        beansMap.forEach((name, bean) -> {
            System.out.println(name + ": " + bean.action());
        });
    }
}
Output
Beans in List: BeanOne: Action from BeanOne BeanTwo: Action from BeanTwo Beans in Map: beanOne: Action from BeanOne beanTwo: Action from BeanTwo
⚠️

Common Pitfalls

1. Missing @Component or @Service annotation: Beans must be annotated to be detected by Spring.

2. Injecting a single bean instead of a collection: Trying to inject one bean when multiple exist causes errors.

3. Using field injection without @Autowired: Spring won't inject beans without the annotation or constructor injection.

java
/* Wrong: No @Autowired, single bean injection when multiple exist */
@Component
class WrongService {
    @Autowired
    private MyBean myBean; // Error if multiple beans exist
}

/* Right: Use List or Map with @Autowired */
@Component
class RightService {
    private final List<MyBean> myBeans;

    @Autowired
    public RightService(List<MyBean> myBeans) {
        this.myBeans = myBeans;
    }
}
📊

Quick Reference

  • Use List<BeanType> to inject all beans in order.
  • Use Map<String, BeanType> to inject beans with their names.
  • Annotate beans with @Component, @Service, or similar.
  • Prefer constructor injection with @Autowired for clarity and testability.
  • Ensure Spring scans the package containing your beans.

Key Takeaways

Inject multiple beans by using @Autowired with List or Map of the bean type.
Annotate all beans with @Component or @Service so Spring can find them.
Use constructor injection for better clarity and easier testing.
Map injection provides bean names as keys, List preserves order.
Avoid injecting a single bean when multiple beans of the same type exist.