Learn how to troubleshoot the ‘No Qualifying Bean of Type Found’ error in Spring Boot. This guide covers common causes and provides solutions to fix dependency injection issues.
You may run into the following error in Spring Boot: "No qualifying bean of type found."
This means Spring can’t find a bean to inject into a class. It’s a common issue that usually stems from problems with bean definitions or the application setup.
Typical Reasons for the Error
- Missing Bean Definition: The class you want to use might not have the necessary annotations like
@Service
,@Component
, or@Bean
. - Component Scanning Issues: The package containing your class may not be included in the component scan, preventing Spring from finding it.
- Multiple Implementations: If several implementations of an interface exist, Spring may not know which one to use.
- Removed Implementation Class: If the implementation class for an interface is deleted, the corresponding bean definition will be missing.
Examples for Each Cause
1. Missing Bean Definition
This occurs when you expect a class to act as a Spring bean, but it lacks the necessary annotations.
MissingService.java
package com.example.account;
public class MissingService { // Missing @Service annotation
public void doSomething() {
System.out.println("Doing something...");
}
}
2. Component Scanning Issues
This happens when your class is in a package that isn’t included in the component scan, preventing Spring from discovering it.
AnotherService.java
package com.example.other;
import org.springframework.stereotype.Service;
@Service
public class AnotherService {
public void execute() {
System.out.println("Executing another service...");
}
}
3. Multiple Implementations
When multiple beans implement the same interface, Spring needs to know which one to use. If this isn’t specified, it can lead to an error.
AccountService.java
package com.example.account;
public interface AccountService {
void createAccount();
}
PersonalAccountService.java
package com.example.account;
import org.springframework.stereotype.Service;
@Service("personalAccountService")
public class PersonalAccountService implements AccountService {
@Override
public void createAccount() {
System.out.println("Personal account created using Personal Account Service.");
}
}
BusinessAccountService.java
package com.example.account;
import org.springframework.stereotype.Service;
@Service("businessAccountService")
public class BusinessAccountService implements AccountService {
@Override
public void createAccount() {
System.out.println("Business account created using Business Account Service.");
}
}
Application.java
package com.example;
import com.example.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Qualifier("personalAccountService") // Specify which implementation to use
private final AccountService accountService;
@Autowired
public Application(AccountService accountService) {
this.accountService = accountService;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
accountService.createAccount(); // Create a new account
}
}
4. Removed Implementation Class
This error occurs when an interface is present, but its implementation class has been deleted. Removing the implementation without removing the interface can lead to this issue.AccountService.java
package com.example.account;
public interface AccountService {
void createAccount();
}
BasicAccountService.java
// BasicAccountService.java (Supposed to be present but removed)
// package com.example.account;
// import org.springframework.stereotype.Service;
// @Service
// public class BasicAccountService implements AccountService {
// @Override
// public void createAccount() {
// System.out.println("Creating account using Basic Account Service.");
// }
// }
Application.java
This application will throw an error because the implementation class is missing.
package com.example;
import com.example.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
private final AccountService accountService;
@Autowired
public Application(AccountService accountService) {
this.accountService = accountService; // Will throw an error if no implementation found
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
accountService.createAccount(); // Attempt to create a new account
}
}
Example: Account Service Implementation
Let’s consider an account management feature in your application. You need an AccountService
to handle the creation and management of accounts.SavingAccountService.java
package com.example.account;
import org.springframework.stereotype.Service;
@Service
public class SavingAccountService implements AccountService {
@Override
public void createAccount() {
System.out.println("Saving account created using Saving Account Service.");
}
}
CheckingAccountService.java
package com.example.account;
import org.springframework.stereotype.Service;
@Service
public class CheckingAccountService implements AccountService {
@Override
public void createAccount() {
System.out.println("Checking account created using Checking Account Service.");
}
}
Application.java
This is the entry point of the Spring Boot application. It starts the application and sets up the context. In this example, we show how to create accounts using the services, utilizing the @Qualifier
annotation to specify which service to use.
package com.example;
import com.example.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Qualifier("savingAccountService") // Using @Qualifier at property level
private final AccountService accountService;
@Autowired
public Application(AccountService accountService) {
this.accountService = accountService;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
accountService.createAccount(); // Create a new account
}
}
Summary
To avoid the “No qualifying bean of type” error in Spring Boot, make sure your classes are correctly annotated and included in the component scan. When using multiple implementations, utilize @Qualifier
to clarify which bean should be used. Also, keep in mind that removing an implementation class while leaving the interface can cause similar issues. With proper configuration of your services and the main application, you can effectively manage accounts without running into bean definition problems.
Leave a Reply