33
votes

I have a Spring boot application.

I get the following error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'birthdayController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.esri.birthdays.dao.BirthdayRepository com.esri.birthdays.controller.BirthdayController.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.esri.birthdays.dao.BirthdayRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at or

Following is code of my Repository class

package com.esri.birthdays.dao;
import com.esri.birthdays.model.BirthDay;
public interface BirthdayRepository extends MongoRepository<BirthDay,String> {
    public BirthDay findByFirstName(String firstName);
}

Following is controller.

package com.esri.birthdays.controller;
@RestController
public class BirthdayController {

    @Autowired
    private BirthdayRepository repository;

Works if they are in same package. Not sure why

13
What package is your main class in? Does its component scanning cover both the repository and controller packages?Andy Wilkinson

13 Answers

80
votes

When you use @SpringBootApplication annotation in for example package

com.company.config

it will automatically make component scan like this:

@ComponentScan("com.company.config") 

So it will NOT scan packages like com.company.controller etc.. Thats why you have to declare your @SpringBootApplication in package one level prior to your normal packages like this: com.company OR use scanBasePackages property, like this:

@SpringBootApplication(scanBasePackages = { "com.company" })

OR componentScan:

@SpringBootApplication
@ComponentScan("com.company")


6
votes

Just put the packages inside the @SpringBootApplication tag.

@SpringBootApplication(scanBasePackages = { "com.pkg1", "com.pkg2", .....})

Let me know.

4
votes

Try annotating your Configuration Class(es) with the @ComponentScan("com.esri.birthdays") annotation. Generally spoken: If you have sub-packages in your project, then you have to scan for your relevant classes on project-root. I guess for your case it'll be "com.esri.birthdays". You won't need the ComponentScan, if you have no sub-packaging in your project.

3
votes

Try this:

    @Repository
    @Qualifier("birthdayRepository")
    public interface BirthdayRepository extends MongoRepository<BirthDay,String> {
        public BirthDay findByFirstName(String firstName);
    }

And when injecting the bean:

    @Autowired
    @Qualifier("birthdayRepository")
    private BirthdayRepository repository;

If not, check your CoponentScan in your config.

3
votes

Spring Boot will handle those repositories automatically as long as they are included in the same package (or a sub-package) of your @SpringBootApplication class. For more control over the registration process, you can use the @EnableMongoRepositories annotation. spring.io guides

@SpringBootApplication
@EnableMongoRepositories(basePackages = {"RepositoryPackage"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
3
votes

In my case @component was not working because I initialized that class instance by using new <classname>().

If we initialize instance by conventional Java way anywhere in code, then spring won't add that component in IOC container.

2
votes

For this kind of issue, I ended up in putting @Service annotation on the newly created service class then the autowire was picked up. So, try to check those classes which are not getting autowired, if they need the corresponding required annotations(like @Controller, @Service, etc.) applied to them and then try to build the project again.

2
votes

By default, in Spring boot applications, component scan is done inside the package where your main class resides. any bean which is outside the package will not the created and thus gives the above mentioned exception.

Solution: you could either move the beans to the main spring boot class(which is not a good approach) or create a seperate configutation file and import it:

@Import({CustomConfigutation1.class, CustomConfiguration2.class})
@SpringBootpplication
public class BirthdayApplication {

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

}

Add beans to these CustomConfiguration files.

0
votes

There will definitely be a bean also containing fields related to Birthday So use this and your issue will be resolved

@SpringBootApplication
@EntityScan("com.java.model*")  // base package where bean is present
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
0
votes

I had the same problem. It worked for me when i removed the private modifier from the Autowired objects.

0
votes
package com.test.springboot;
        @SpringBootApplication
    @ComponentScan(basePackages = "com.test.springboot")
    public class SpringBoot1Application {

        public static void main(String[] args) {
            ApplicationContext context=  SpringApplication.run(SpringBoot1Application.class, args);

=====================================================================

package com.test.springboot;
    @Controller
    public class StudentController {
        @Autowired
        private StudentDao studentDao;

        @RequestMapping("/")
        public String homePage() {
            return "home";
        }
0
votes

Another fun way you can screw this up is annotating a setter method's parameter. It appears that for setter methods (unlike constructors), you have to annotate the method as a whole.

This does not work for me: public void setRepository(@Autowired WidgetRepository repo)

but this does: @Autowired public void setRepository(WidgetRepository repo)

(Spring Boot 2.3.2)

0
votes

When I add @ComponentScan("com.firstday.spring.boot.services") or scanBasePackages{"com.firstday.spring.boot.services"} jsp is not loaded. So when I add the parent package of project in @SpringBootApplication class it's working fine in my case

Code Example:-

package com.firstday.spring.boot.firstday;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = {"com.firstday.spring.boot"})
public class FirstDayApplication {

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

}