扩展CrudRepository的@Autowired接口如何工作?我想有一些见解

Paw*_*til 8 autowired spring-data spring-boot

假设我的接口扩展CrudRepository如下

 @Repository
    public interface EmployeeRepository extends CrudRepository<Employee, Integer> 
    {
    }
Run Code Online (Sandbox Code Playgroud)

我在Service类中使用EmployeeRepository接口,如下所示

@Service
public class EmployeeService 
{

 @Autowired 
  EmployeeRepository employeeRepository;


 public List<Employee> getAllEmployee()
 {
     List<Employee> listEmp=new ArrayList<Employee>();
     employeeRepository.findAll().forEach(listEmp::add);
     return listEmp;


 }
}
Run Code Online (Sandbox Code Playgroud)

和控制器如下

@RestController
public class WelcomeController 
{
    @Autowired
    EmployeeService empservice;

    @RequestMapping("/employees")
    public List<Employee> getEmployees()
    {
        return empservice.getAllEmployee();
    }

}
Run Code Online (Sandbox Code Playgroud)

它给出了以下例外

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'welcomeController'的bean时出错:通过字段'empservice'表示的不满意的依赖关系:创建名为'employeeService'的bean时出错:通过字段'employeeRepository'表示的不满意的依赖关系

错误很明显,因为任何类都没有实现接口EmployeeRepository

@Autowired  
EmployeeRepository employeeRepository;
Run Code Online (Sandbox Code Playgroud)

自动装配将失败,因为没有类正在实施employeeRepository.

尽管如此,我对它如何工作感到困惑,因为我在GitHub和教程上看到的每个代码都运行得很好.

我在哪里出错了@Autowired如何处理扩展CrudRepository的接口,即使没有类正在实现它; 这是自动装配的基本规则?也就是说,如果您要自动连接任何接口,那么至少有一个类必须实现该接口,然后自动装配将成功.

Rub*_*ben 14

嗯,确实已经有一个关于Spring Data Repositories的很好的答案:Spring Data Repositories 如何实际实现?.但是,在阅读你的问题时,我认为对于@Autowired作品的方式存在一些混乱.让我试着给出事件的高级序列:

  1. 您将依赖项放在EmployeeRepository代码中:

    
    @Autowired 
    private EmployeeRepository employeeRepository;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过执行步骤(1),您向Spring容器指示在其启动过程中它应该找到实现的类的实例并将其EmployeeRepository注入到@Autowired注释的目标中.我想在此强调这样一个事实:为了使注入正常工作,您应该在运行时期间在Spring容器中实现所需接口的类实例,而不是在编译过程中.

  3. 所以现在出现了一个逻辑问题:" UserRepository如果我们没有明确定义该类,那么从启动过程中实现Spring容器中出现的那个类开始"?

  4. 这是来自Oliver的详细答案:Spring Data存储库是如何实际实现的?.简而言之,在容器引导过程中Spring Data会扫描所有存储库接口; 创建实现这些接口的新类(代理); 将这些类的实例放入Spring容器中,允许@Autowired查找和注入它们,就像它对容器中的任何其他Spring bean一样.

而且,这些过程只有在您设置并正确配置Spring Data时才有效,否则注入会失败.

希望这可以帮助.