Fixing No Qualifying Bean of Type Found Error in Spring Boot

Fixing No Qualifying Bean of Type Found Error in Spring Boot

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.