【问题标题】:Purpose of Service Interface Class in Spring BootSpring Boot 中服务接口类的用途
【发布时间】:2020-10-17 07:43:49
【问题描述】:

我的问题是关于接口类的使用。我对 Spring 还很陌生,所以如果这过于简单,请多多包涵。

首先,当您可以在 BoxService 中声明 find all 时,这里有一个 IBoxService 接口有什么意义。其次,在控制器中如何使用 IBoxService。意思是,我们正在调用 IBoxService.findAll()。但是,这如何与 BoxService 类相关联。如果多个服务类实现了 IBoxService 会怎样?这是java的东西还是Spring注入的东西。谢谢。

package com.xyz.service;

import com.xyz.model.Box;
import java.util.Set;

public interface IBoxService {

    Set<Box> findAll();
}

package com.xyz.service;

import com.xyz.model.Box;
import com.xyz.repository.BoxRepository;
import java.util.Set;
import org.springframework.stereotype.Service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;

@Service
@AllArgsConstructor
@Slf4j
@Transactional
public class BoxService implements IBoxService {
@Autowired
private BoxRepository boxRepo;

@Override
public Set<City> findAll() {

    return (Set<City>) repository.findAll();
}

}

package com.xyz.controller;

import com.xyz.model.Box;
import com.xyz.service.IBoxService;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;    

@RestController
@RequestMapping("/api/box")
public class BoxController {

    @Autowired
    private IBoxService boxService;

    @GetMapping
    public ResponseEntity<Set<Boxes>> allBoxes() {

        return (Set<Box>) boxService.findAll();
    }
}

【问题讨论】:

    标签: java spring spring-boot model-view-controller dependency-injection


    【解决方案1】:

    创建服务层接口有多种原因。第一个也是最重要的原因是可测试性。您可以创建服务接口的模拟并轻松测试您的代码,如果您无法使用模拟库创建模拟,那么您可以创建测试存根。

    还有一个原因是,我们可以实现 Controller 和 Service 层之间的松耦合。假设您想完全更改服务的实现,您可以创建新的服务实现并通过限定符名称注入新 bean 来注入该实现

    【讨论】:

    • 谢谢。你知道自动装配是如何引用 BoxService 的吗?只是好奇为什么在没有明确分配给 BoxService 的情况下在控制器中使用 IBoxService 会起作用。如果 BoxService2 也实现了 IBoxService 会怎样?
    • 如果有多个实现,您可以使用@Qualifier 命名实现。阅读:baeldung.com/spring-qualifier-annotation 或者您可以使用 @Primary 将其中一个实现标记为主要实现
    【解决方案2】:

    请了解基本的Java和接口的使用。 Spring boot 只是对 Java 的抽象,因此所有基本概念都照原样适用。

    回到您的问题 IBoxService 是一个允许在控制器级别注入所需实现的接口。到目前为止,只有 IBoxServic 的实现是 BoxService,因此它会自动注入。如果您有多个实现,则需要使用限定符注释来指定需要注入的实现类型。或者您可以使用类名自己创建对象 bu

    考虑以下:

    IBoxService 由两个类 BoxService 和 TiffinBoxService 实现

    现在在控制器中你可以注入你想要的实现。这让我们可以实现隐藏内部细节的界面原理。

    在这种情况下,作为控制器的用户不需要知道内部使用的是哪个类,因为我们使用的是接口的引用。

    List 接口是最好的例子,它以 ArrayList 和 LinkedList 作为实现类。

    希望有用!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 2016-07-16
      • 2019-10-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      相关资源
      最近更新 更多