简体   繁体   中英

@ComponentScan and @Autowired fail to inject from a specific package

I am aware of the many similar questions about this issue on SO, however, non of them solved my problem. I have a Spring REST project and I am using Spring Tool Suite (STS) 3.5.1 RELEASE.

The application class:

package com.example.rest;

@ComponentScan({"com.example.repositories", "com.example.config", "com.example.services",    "com.example.rest", "com.example.jms"})
@EnableAutoConfiguration
public class Application 
{
  ... //declaring some beans for JMS
}

The repository class:

package com.example.repositories;

@Repository
public interface ActorRepository extends MongoRepository<Actor, String> 
{

   public Actor findByFNameAndLName(String fName, String lName);
   public Actor findByFName (String fName);
   public Actor findByLName(String lName);

}

The Service class (Autowire fails here to inject actorRepository):

package com.example.services;

@Service
public class ActorService 
{
  @Autowired
  private ActorRepository actorRepository;
  ....
}

The REST service (Autowired fails to inject actorService -I assume it is because ActorService failed to inject ActorRepository):

package com.example.rest;

@RestController
@RequestMapping("/actors")

public class ActorRESTService 
{
  private static final Logger logger = Logger.getLogger(ActorRESTService.class);

  @Autowired 
  private ActorService actorService;

  ....
}

The reason I believe it is happening because @ComponentScan is not scanning the repositories package is that in STS, Spring classes have a little S on the right top corner of thier Java icon. And this appears on all classes that should be scanned (the componenets except for anything in the repositories package). Moving the repository classes to the rest package makes them scanned (No Idea why!).

This is part of the excpetion I get when I try to run the project using Spring Boot App.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actorService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.repositories.ActorRepository com.example.services.ActorService.actorRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.repositories.ActorRepository] 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:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:683)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:944)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:933)
at com.example.rest.Application.main(Application.java:94)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.repositories.ActorRepository com.example.services.ActorService.actorRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.repositories.ActorRepository] 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 16 common frames omitted

 .....  

The Repositories have to be in the same packaege or a sub-package of the main(Application) class. This is the default behavior in spring boot. To keep things clean you can also put the repos in a sub package, like com.example.rest.repo in your case. Or as M. Deinum sugested you can put the main class in the base package so that spring can handle that automaticaly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM