๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG*************************** APPLICATION FAILED TO START *************************** Description: Parameter 0 of method userController in com.devinhyderabad.config.AppConfig required a single bean, but 2 were found: - userServiceImpl: defined in file [/com/devinhyderabad/service/UserServiceImpl.class] - mockUserService: defined in file [/com/devinhyderabad/service/MockUserService.class] Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

โšก Quick Fix Works 80% of the time

Add @Primary to the implementation you want Spring to use by default.

@Service @Primary public class UserServiceImpl implements UserService {}

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

Spring found multiple classes implementing the same interface (e.g., `UserService`). When you tried to autowire `UserService`, Spring didn't know which one to inject, so it crashed and asked you to clarify which one is the primary choice.

The HITEC City Parking Spot Analogy:

You ask a friend to bring you 'a soda'. They look in the fridge and see both Coke and Pepsi. They freeze, unsure which one you want, and refuse to bring either until you specify (@Qualifier) or tell them your default favorite (@Primary).

๐Ÿ” How to Reproduce Confirm this is your error

Create two classes `UserServiceImpl` and `MockUserService` that both implement `UserService`. Annotate both with `@Service`. In a controller, `@Autowired private UserService userService;`. Run the app.

๐Ÿ› ๏ธ Solutions (5 Ways to Fix)

Solution 1โœ“ Most common cause

Mark one bean as @Primary

๐Ÿ‘‰ Use this when you have a default implementation and want Spring to pick it automatically.

Adding @Primary tells Spring: 'If you find multiple candidates, always choose this one.'

@Service @Primary public class UserServiceImpl implements UserService { ... }
Solution 2

Use @Qualifier at the injection point

๐Ÿ‘‰ Use this when you want explicit control over which bean is injected at different locations.

Tell Spring exactly which bean name to inject at the exact @Autowired field.

@RestController public class UserController { @Autowired @Qualifier("mockUserService") private UserService userService; }
Solution 3

Use a specific implementation type instead of interface

๐Ÿ‘‰ Use this if you are okay with tight coupling and don't want to use @Qualifier.

Instead of autowiring the interface, autowire the exact implementation class.

@RestController public class UserController { @Autowired private UserServiceImpl userService; // Specifically asks for UserServiceImpl }
Solution 4

Exclude one implementation from component scanning

๐Ÿ‘‰ Use this if one of the beans was created by mistake or for testing and shouldn't be in the app.

Remove the @Service annotation from the unwanted class, or use @ComponentScan excludeFilters to block it.

@SpringBootApplication @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MockUserService.class)) public class Application { ... }
Solution 5

Combine implementations using a List/Map injection

๐Ÿ‘‰ Use this if you actually want to use all implementations dynamically (e.g., plugin pattern).

Spring can inject all beans of a type into a List. You can then iterate over them.

@Service public class Dispatcher { @Autowired private List<UserService> userServices; // Spring injects all implementations }

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Throws NoUniqueBeanDefinitionException.

Spring Boot 3.x

Provides the 'Consider marking one of the beans as @Primary' FailureAnalyzer message.

๐Ÿ›ก๏ธ How to Prevent This Next Time

When creating mock or alternative implementations for testing, ensure they are only active in specific profiles using `@Profile("test")`.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase