Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot @autowired does not work, classes in different package

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

like image 911
Aniket Patil Avatar asked Dec 19 '15 04:12

Aniket Patil


People also ask

Why Autowired is not working in Spring boot?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

Can we use @autowired in a class?

You can apply @Autowired to constructors as well. A constructor @Autowired annotation indicates that the constructor should be autowired when creating the bean, even if no <constructor-arg> elements are used while configuring the bean in XML file. Let us check the following example.

What can be used instead of Autowired?

Both of these annotations use the 'AutowiredAnnotationBeanPostProcessor' to inject dependencies. '@Autowired' and '@Inject' can be used interchangeable to inject Spring beans.


9 Answers

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")


like image 69
jgr Avatar answered Oct 09 '22 11:10

jgr


Just put the packages inside the @SpringBootApplication tag.

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

Let me know.

like image 36
LucaT Avatar answered Oct 09 '22 13:10

LucaT


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.

like image 42
mchlfchr Avatar answered Oct 09 '22 12:10

mchlfchr


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.

like image 43
Gemasoft Avatar answered Oct 09 '22 13:10

Gemasoft


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);
    }
}
like image 21
sasanka Avatar answered Oct 09 '22 12:10

sasanka


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.

like image 40
Nikhil Kakade Avatar answered Oct 09 '22 11:10

Nikhil Kakade


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.

like image 21
Sreeni Avatar answered Oct 09 '22 11:10

Sreeni


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.

like image 37
GSB Avatar answered Oct 09 '22 13:10

GSB


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

like image 35
Prerit Jain Avatar answered Oct 09 '22 11:10

Prerit Jain