项目树更改后的Spring UnsatisfiedDependencyException

时间:2017-09-30 20:50:42

标签: java spring spring-boot

我是Spring的新手,我正在努力做一个简单的休息应用程序。当我将所有文件放在一个包中时,应用程序运行正常。由于我改变了我的项目组织,我无法构建我的项目。我收到了这个错误:

2017-09-30 22:32:48.428  WARN 9428 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'application': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'socketApp.dal.repository.CustomerRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    2017-09-30 22:32:48.431  INFO 9428 --- [           main] utoConfigurationReportLoggingInitializer : 

    Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
    2017-09-30 22:32:48.495 ERROR 9428 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

    Description:

    Field repository in socketApp.main.Application required a bean of type 'socketApp.dal.repository.CustomerRepository' that could not be found.


    Action:

    Consider defining a bean of type 'socketApp.dal.repository.CustomerRepository' in your configuration.

    2017-09-30 22:32:48.496 ERROR 9428 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@16267862] to prepare test instance [hello.GreetingControllerTests@47f08b81]

我当前的项目树看起来像这样

src 
  main 
    java
      app
        dal
          model
            -Customer.java
          repository
            -CustomerRepository.java
        main
          -Aplication.java
        webServices
          -GreetingController.java

这是我的Customer.java文件:

package socketApp.dal.model;

import org.springframework.data.annotation.Id;


public class Customer {

    @Id
    public String id;

    public String firstName;
    public String lastName;

    public Customer() {}

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format(
                "Customer[id=%s, firstName='%s', lastName='%s']",
                id, firstName, lastName);
    }

}

我的CustomerRepository.java文件:

    package socketApp.dal.repository;


import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import socketApp.dal.model.Customer;

@Repository
public interface CustomerRepository extends MongoRepository<Customer, String> {

    public Customer findByFirstName(String firstName);
    public List<Customer> findByLastName(String lastName);


}

我的Application.java

    package socketApp.main;



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import socketApp.dal.model.Customer;
import socketApp.dal.repository.CustomerRepository;

@SpringBootApplication

public class Application implements CommandLineRunner{

    @Autowired 
    private CustomerRepository repository;

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

    @Override
    public void run(String... args) throws Exception {

        repository.deleteAll();

        // save a couple of customers
        repository.save(new Customer("Alice", "Smith"));
        repository.save(new Customer("Bob", "Smith"));

        // fetch all customers
        System.out.println("Customers found with findAll():");
        System.out.println("-------------------------------");
        for (Customer customer : repository.findAll()) {
            System.out.println(customer);
        }
        System.out.println();

        // fetch an individual customer
        System.out.println("Customer found with findByFirstName('Alice'):");
        System.out.println("--------------------------------");
        System.out.println(repository.findByFirstName("Alice"));

        System.out.println("Customers found with findByLastName('Smith'):");
        System.out.println("--------------------------------");
        for (Customer customer : repository.findByLastName("Smith")) {
            System.out.println(customer);
        }

    }
}

最后我的GreetingController.java

   package socketApp.webServices;



import socketApp.dal.repository.CustomerRepository;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import socketApp.dal.model.Customer;
import socketApp.dal.model.Greeting;

@RestController
public class GreetingController {

    @Autowired 
    private CustomerRepository repository;


    @RequestMapping("/")
    public List<Customer> getAllCustomers(){
        // fetch all customers
    return repository.findAll();
    }
} 

2 个答案:

答案 0 :(得分:3)

您必须将Application类移到一个包中,以便该类位于其他包之上,或者通过scanBasePackagesscanBasePackageClasses手动指定basePackage对于@SpringBootApplication启动的组件扫描。

了解更多详情。

答案 1 :(得分:1)

默认情况下,@SpringBootApplication将仅扫描包含注释类包的组件“降序”。

因此,在您的情况下,因为主类位于socketApp.main且存储库位于socketApp.dal.repository中,所以它将无法找到。

您有两种选择:

Application移至包socketApp

package socketApp;    

...

@SpringBootApplication
public class Application implements CommandLineRunner {
...

或添加其他@ComponentScan注释。在你的情况下,它将是:

@SpringBootApplication
@ComponentScan("socketApp")
public class Application implements CommandLineRunner {
...

我认为第一种选择更好。