Reputation: 121
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?
Upvotes: 4
Views: 32062
Reputation: 16
In my case I have created service class in different folder in place of the folder in which controller is present.
check the folder at least once.
Upvotes: 0
Reputation: 121
If you're using MockBean with Junit for testing controllers, be sure to add a mock bean of whatever dependency is reported missing on the log even if you might not be using it. Like @MockBean private BookService bookService;
Upvotes: 0
Reputation: 659
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
Upvotes: 0
Reputation: 3188
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
Upvotes: 2
Reputation: 12953
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
Upvotes: 3