RamPrakash
RamPrakash

Reputation: 3264

Why is this @ComponentScan not working in my spring boot application?

I am learning spring boot. This is my spring boot project structure. I do intentionally keep my application.java in a different package to learn about @ComponentScan

Project source - https://github.com/kitkars/spring-boot

project structure

Error :

The application failed to start due to below error.

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

Description:

Field productRepository in com.test.service.ProductService required a bean of type 'com.test.repository.ProductRepository' 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 'com.test.repository.ProductRepository' in your configuration.


Process finished with exit code 1

This is my Application.java

@SpringBootApplication
@ComponentScan(basePackages = "com.test")
public class Application {

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

}

Now If I move my Application.java under com.test, everything works just great.

What If my Application.java is not under com.test - can it not use the ComponentScan packages and start from there? All the controller, services, repositories etc are present under com.test.

Upvotes: 3

Views: 32844

Answers (6)

PowerAktar
PowerAktar

Reputation: 2428

For me, removing the @ComponentScan did the job.

SpringBoot should pick up all your components automatically, so long as your application structure is like this:

|-->package1
|-->package2
|Main.java

Upvotes: 0

Junior Rodrigues
Junior Rodrigues

Reputation: 21

resolving do this in my application class.

@Configuration
@SpringBootApplication
@ComponentScan(basePackages = "{lamc.bar.*}")

Upvotes: 0

Boris Velichko
Boris Velichko

Reputation: 11

Please check the dependency 'org.springframework:spring-context-indexer if you have one, of course. In my case, this library has caused problems with submodules. The problem was that only beans of the current gradle project were included in the index.

Upvotes: 1

Yevgen
Yevgen

Reputation: 1667

Spring Boot relies heavily on default configuration. Consider this excerpt from @EnableAutoConfiguration annotation.

The package of the class that is annotated with @EnableAutoConfiguration, usually via @SpringBootApplication, has specific significance and is often used as a 'default'. For example, it will be used when scanning for @Entity classes. It is generally recommended that you place @EnableAutoConfiguration (if you're not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.

The same logic implies to @ComponentScan, @EnableJpaRepositories and the above mentioned @EntityScan annotations. So, if you want to take control of component scanning, you should specify base packages explicitly for all of those annotations.

@SpringBootApplication(scanBasePackages = "com.test")
@EnableJpaRepositories(basePackages = "com.test")
@EntityScan(basePackages = "com.test")
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

Also note that in your case there is no need to use another @ComponentScan as you can provide arguments to Spring Boot's @ComponentScan via scanBasePackages attribute.

Upvotes: 4

TranNgocKhoa
TranNgocKhoa

Reputation: 441

You should remove @Repository in com/test/repository/ProductRepository.java.

Upvotes: -3

Andronicus
Andronicus

Reputation: 26046

The class annotated with @SpringBootApplication should be in your root package (by default all classes in this package and subpackages are scanned) or you need to specify other packages (controller, entity and others) in @ComponentScan.

Official documentation states:

We generally recommend that you locate your main application class in a root package above other classes.

Upvotes: 7

Related Questions