一尘不染

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

spring-boot

假设我的界面扩展CrudRepository如下

 @Repository
    public interface EmployeeRepository extends CrudRepository<Employee, Integer> 
    {
    }

并且我在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;


 }
}

和控制器如下

@RestController
public class WelcomeController 
{
    @Autowired
    EmployeeService empservice;

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

}

它给出了以下异常

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为“
welcomeController”的bean时出错:通过字段“ empservice”表达的满意度不满意​​:创建名称为“
employeeService”的bean出错:通过字段“ employeeRepository”表达的满意度不满足

该错误显而易见,因为任何类均未实现EmployeeRepository接口,并且

@Autowired  
EmployeeRepository employeeRepository;

自动连线将失败,因为没有任何类正在实现employeeRepository。

尽管如此,我对它的工作方式还是感到困惑,因为我在GitHub和教程上看到的每个代码都能完美地工作。

我哪里出问题了,即使没有类实现,@
Autowired在扩展CrudRepository的接口上如何工作;自动装配的基本规则是什么?也就是说,如果您要自动连接任何接口,则至少必须有一个类必须实现该接口,然后自动装配才能成功。


阅读 388

收藏
2020-05-30

共1个答案

一尘不染

嗯,关于Spring Data Repository确实已经有了一个很好的答案,具体描述如下:Spring Data
Repository是如何实现的?。但是,在阅读您的问题时,我相信@Autowired工作方式会有些混乱。让我尝试给出事件的高级顺序:

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

    @Autowired
    

    private EmployeeRepository employeeRepository;

  2. 通过执行步骤(1),您可以指示Spring容器在其 启动过程中* 应该找到该类的实例,该实例实现EmployeeRepository并将其注入到@Autowired注释的目标中。我要在此 强调 一个事实,为了使注入正常工作,您应该在 运行时而不是在编译过程中 ,在Spring容器中让类的实例 实现所需的接口*

  3. 因此,现在出现了一个逻辑问题:“ UserRepository如果我们没有明确定义该类,那么在Spring容器的启动过程中,该类将在Spring容器中实现的?”

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

同样,这些过程仅在您设置了Spring Data并正确配置后才起作用,否则实际上注入将失败。

希望这可以帮助。

2020-05-30