Spring Boot中的业务层(Service)是否要创建接口,以及如果Service有多个实现类,如何让Spring知道该注入哪个Impl类的分析

参考文档:Spring中 如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?
关于Spring Boot中的业务层(Service)是否要创建接口的分析

一、Spring Boot中的业务层(Service)是否要创建接口?

借助Spring Boot框架开发web项目时,在业务层(Service)这一部分,标准做法是:定义一个接口,然后再一个或多个类去实现。那么疑问来了:

为什么我们要维护两份同构代码,而不直接使用一个类呢?

不创建接口,通过把业务实现类直接通过注解@Autowired注入控制层Controller,也一点不耽误功能的实现啊,那么我为什么还要创建接口?

网上大部分回答都是说什么面向对象的解耦云云,引经据典,说得都很好,然而,都没有从根本上回答我们关心的问题:为什么要用接口?

业务层(Service)中为什么一定要用接口,不用行不行?回答:不是必须要使用接口,但强烈建议使用接口。

情景1: 在开源框架中有很多这种情况,就是某个功能支持用户自定义扩展.说白了,它提供了一个接口,我们只需要实现这个接口,把我们自己的实现逻辑补上,就可以让框架按照我们的逻辑来执行.问题来了,框架的作者并不知道我们的实现类是什么,如果不定义一个接口,那么要如何在框架中调用我们的实现类呢?

情景2: 我和同事分别做项目的2个不同功能模块,但是同事的功能中却需要调用我这头实现的部分逻辑.为了让他有一个"占位符"可用,我是不是应该快速的写个接口扔给他呢?

情景3: 一个适配器功能,或是说一个简单的工厂类,如果没有定义接口,那么面对众多实现类,要如何统一操作呢?

情景4: 想让项目的代码符合某种"规范",但是又不可能看着别人写代码吧,那好办,先出一套接口,然后你们就看着办~

情景5: java中没有多继承,但是可以多实现接口,那么就有一件很有趣的事情了,一个实现类可以实现多个接口,然后此时接口可以有选择的暴露实现类的部分方法,做到"窄化"实现类功能的目的。

当然例子还有很多,这些情况其实可以说是接口好处的体现,所以java有面向接口编程的建议,但是说回Service层一定要有接口吗?那到未必,因为说到底,多一个接口仅仅是扩展性和某些情况下有优势,但是是否会用到接口的便利性,不确定的情况下我们未必一定要为"可能"买单,只是多写那几行代码,付出一点就可能避免"未来"的大"麻烦",何乐而不为!?

下面简单列出Spring Boot中业务层(Service)的创建步骤及应用:

  1. 接口及实现类命名方式,接口XXXService,实现类:XXXServiceImpl。

  2. 实现类XXXServiceImpl需添加注解@Service,并指明名称,如@Service("companyService")

  3. 在实现类中,通过注解@Autowired,注入数据仓库层Repository接口;

当实现的接口涉及数据库数据的删除或修改时,方法上一定要添加注解@Transactional,否则会执行不成功。

二、 如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?

  1. 为每个service的impl都指定名称(使用@Service(“名称”)

  2. Controller中注入service的时候使用名称来指定注入哪一个:

    (1)@Autowired 按类型进行注入

    @Autowired
    @Qualifier("名称") 
    

    (2)@Resource按名称进行注入

    @Resource(name="名称")
    

例子:

service接口:

public interface HumanService {
    public String name();
}

接口Impl实现类:

@Service("teacherService")
public class TeacherServiceImpl implements HumanService {
    @Override
    public String name() {
        System.out.println("teacher");
        return "teacher";
    }
}
 
@Service("doctorService")
public class DoctorServiceImpl implements HumanService {
    @Override
    public String name() {
        System.out.println("doctor");
        return "doctor";
    }
}

controller层:

@RestController
public class HumanController {
//    @Resource(name="doctorService")
    @Autowired
    @Qualifier("teacherService")
    private HumanService humanService;

    @RequestMapping("/name")
    public String name(){
        return humanService.name();
    }
}

以上

### 回答1: Spring Boot常见的注解有: 1. @SpringBootApplication:用于标记主,表示该Spring Boot应用的入口。该注解主要包含了@ComponentScan、@EnableAutoConfiguration和 @Configuration三个注解。 2. @RestController:用于标记Controller,表示该Spring MVC的控制器,并且会自动将返回的数据转换为JSON格式。 3. @RequestMapping:用于映射请求URL和Controller方法之间的关系,可以用在级别和方法级别。在级别上使用时,会为该的所有方法的URL添加一个前缀。 4. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping:这些注解分别用于标记GET、POST、PUT、DELETE请求的处理方法。它们与@RequestMapping的作用似,用于指定请求的URL和HTTP方法。 5. @RequestParam:用于从请求参数获取值,将请求参数与方法参数进行绑定。 6. @PathVariable:用于从URL路径获取值,将路径变量与方法参数进行绑定。 7. @RequestBody:用于将请求体的内容绑定到方法参数上,常用于接收JSON格式的请求数据。 8. @ResponseBody:用于将方法返回的对象转换为HTTP响应体,并将其发送给客户端。 9. @Autowired:用于自动注入依赖对象,Spring Boot会自动扫描并创建相应的对象,并将它们注入到标记了@Autowired的属性上。 10. @Configuration:用于标记配置,指示Spring Boot需要对该进行额外配置。 以上只是一些常见的注解,Spring Boot还有许多其他的注解供开发者使用,用于不同的场景和功能需求。 ### 回答2: Spring Boot是一个Java框架,提供了很多常见的注解来简化开发。以下是一些常见的Spring Boot注解: 1. @SpringBootApplication:这是一个组合注解,用于标注主。它包含了@EnableAutoConfiguration、@ComponentScan和@Configuration注解,用于自动配置、扫描组件和声明配置文件。 2. @RestController:该注解用于标注一个,表示这是一个RESTful风格的控制器,用于处理HTTP请求和返回响应。 3. @RequestMapping:用于将请求映射到处理方法或控制器上。 4. @Autowired:用于自动装配Bean,通过依赖注入实现组件的自动装配。 5. @Component:用于将标记为一个Spring组件,通过自动扫描和注册,将其作为Bean管理。 6. @Configuration:标识该是一个配置,用于声明Spring的配置信息。 7. @Value:用于注入属性值,从配置文件读取。 8. @PathVariable:用于获取URL的路径参数。 9. @RequestParam:用于获取HTTP请求的请求参数。 10. @ResponseBody:用于将方法的返回值直接作为HTTP响应体返回。 11. @ExceptionHandler:用于捕获处理方法抛出的异常,并进行统一处理。 12. @Transactional:用于标记一个方法或需要进行事务管理。 13. @Service:用于标记一个为服务的组件。 14. @Repository:用于标记一个为数据访问的组件。 15. @Aspect:用于声明一个切面,定义横切关注点和通知型。 以上只是常见的一些Spring Boot注解,还有其他更多的注解用于实现不同的功能和特性。 ### 回答3: Spring Boot常见的注解包括: 1. @SpringBootApplication:用于标记主,表示这是一个Spring Boot应用程序的入口点。它是由三个注解组成的组合注解:@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan。 2. @RestController:用于标记一个,表示该是一个RESTful风格的控制器。它将的方法的返回值直接作为响应内容,而不是返回视图。 3. @RequestMapping:用于映射HTTP请求的URL路径到方法上。可以用在和方法上,用于指定处理请求的路径。 4. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping:这些注解分别用于映射HTTP的GET、POST、PUT、DELETE请求到方法上,可以指定路径,并且支持Ant风格的路径匹配。 5. @PathVariable:用于将URL路径的参数绑定到方法的参数上。通常与@RequestMapping一起使用,用于处理带有路径参数的请求。 6. @RequestParam:用于从请求的URL、查询参数或者表单参数获取参数的值,并绑定到方法的参数上。 7. @RequestBody:用于接收HTTP请求的请求体,并绑定到方法的参数上。通常用于处理POST请求的JSON/XML数据。 8. @ResponseBody:用于将方法的返回值直接作为响应内容返回给客户端。通常用于处理RESTful风格的API请求。 9. @Autowired:用于自动装配依赖的Bean。它可以注入Spring容器的Bean,减少手动配置依赖的繁琐操作。 10. @ConfigurationProperties:用于将配置文件的属性值绑定到Spring Boot应用程序的配置。 以上是Spring Boot常见的注解,这些注解可以帮助我们更方便地开发和配置Spring Boot应用程序。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值