How to fix “Field … required a bean of type … that could not be found” exception Spring Boot

Viewed 10735

I am working with spring boot tutorial about @Autowired and @Primary annotation
Below you can find my main class

package com.example.springtest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import service.Animal;

@SpringBootApplication
public class SpringtestApplication {
@Autowired
private Animal animal;

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

}

}

Animal interface (the interface that i should autowired)

package service;

public interface Animal {


      String characteristics();
}

Dog class (the primary implementation of Animal interface)

package service;


import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

@Primary
@Service
public class Dog implements Animal {

    @Override
    public String characteristics() {
        return "Bark";
    }
}

Cat class (the second implementation of Animal interface)

package service;


import org.springframework.stereotype.Service;

@Service
public class Cat implements Animal {

    @Override
    public String characteristics() {
        return "Meow";
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springtest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

When I run the app there is a problem with injection of animal and I get following error:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field animal in com.example.springtest.SpringtestApplication required a bean of type 'service.Animal' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'service.Animal' in your configuration.

What could be the reason that Spring cannot do the autowiring?

3 Answers

Your configuration file will only pick up services that are in subpackages.

Your SpringtestApplication application is currently in the package package com.example.springtest This means that it will only autowire beans under that package. Ex com.example.springtest.services

However, it looks like your actual service Dog service is located in the package service so it will not be seen.

Try moving your services to com.example.springtest.services

You need to add to your main class a @ComponentScan annotation, telling it to scan the package of the services, otherwise it will not initialize these beans

Spring will do a component scan under packages com.example.springtest.*. as your spring boot application is defined there and it acts as root of the application.

As you have defined your Animal interface, Dog and Cat service under service package, Spring has no way to find out these beans and hence it can not autowire it.

Package hierarchy should like follows :

com
 --example
    --springtest
       -- service
Related