zoukankan      html  css  js  c++  java
  • 一个接口多个实现类,controller层如何指定特定实现类进行调用?

    背景

    今天面试一家公司,面试官问了一个问题“在Service层一个接口有多个实现类,那么在controller层如何指定某个实现类进行调用呢?”,给我问懵了,因为之前做项目没有遇到过这种情况,都是一个接口对应一个实现类。
    如接口为:

    public interface BuyerService {
        //查询订单详情
        OrderDTO getOrderOne(String openid,String orderId);
    
        //取消订单
        OrderDTO cancelOrder(String openid,String orderId);
    }
    
    

    对应的实现类为:

    public class BuyerServiceImpl implements BuyerService {
      
        @Override
        public OrderDTO getOrderOne(String openid, String orderId) {
            return checkOrderOwner(openid,orderId);
        }
    
        @Override
        public OrderDTO cancelOrder(String openid, String orderId) {
            OrderDTO orderDTO = checkOrderOwner(openid,orderId);
            if(orderDTO == null){
                log.error("【取消订单】 查不到该订单,orderId={}",orderId);
                throw new SellException(ResultEnum.ORDER_NOT_EXIST);
            }
            return orderService.cancel(orderDTO);
        }
    }
    
    

    如果一个接口有多个实现类,在Controller层注入后调用,怎么知道调用的是接口的哪个方法呢?
    经过一番测试,和查找资料,终于找到了结果。

    一个接口对应多个实现类

    一个接口对应对个实现类,需要注入指定的实现类。
    如:Interface接口下有两个实现类InterfaceImpl1InterfaceImpl2
    接口:

    package com.example.service;
    public interface Interface1 {
        void fun1();
    }
    

    对应实现类1InterfaceImpl1

    @Service("s1")
    public class Interface1Impl1 implements Interface1 {
        @Override 
        public void fun1() {
            System.out.println("接口1实现类 ...");
        } 
        public void fun2(){
            System.out.println("接口1实现类1 fun2 ...");
        } 
    }
    

    对应实现类2InterfaceImpl2

    @Service("s2") 
    public class Interface1Impl2 implements Interface1 { 
        @Override 
        public void fun1() { 
           System.out.println("接口1实现类 ...");
        } 
        public void fun2(){
           System.out.println("接口1实现类2 fun2 ..."); 
        } 
    } 
    

    解决方法

    指明实现类的优先级

    在写实现类的时候事先指明实现类的优先级,注入的时候就会使用优先级高的实现类。在controller中注入接口,默认使用的是Primary 标注的实现类的方法
    如:

    @Service("s1")
    @Primary     //**同一个接口的多个实现类,最多只能有一个添加该注解**
    public class InterfaceImpl1 implements Interface {
         。。。
    }
    

    通过 @Autowired@Qualifier 配合注入

    @Autowired
    @Qualifier("interface1Impl1")
    Interface1 interface1;    //正常启动
    

    使用@Resource注入,根据默认类名区分

    @Resource(name = "interface1Impl1")
    Interface1 interface1;    //正常启动
    

    使用@Resource注入,根据@Service指定的名称区分

    @Resource(name = "s1")
    Interface1 interface1;    //正常启动
    
  • 相关阅读:
    C#实体类对象修改日志记录
    C#中关于增强类功能的几种方式
    Elasticsearch入坑指南之RESTful API
    React入门实例
    .Net Core+Vue.js+ElementUI 实现前后端分离
    ElasticSearch入坑指南之概述及安装
    MySQL优化技巧
    RabbitMQ入门教程——路由(Routing)
    RabbitMQ入门教程——发布/订阅
    RabbitMQ入门教程——工作队列
  • 原文地址:https://www.cnblogs.com/xiaozhengtongxue/p/13736829.html
Copyright © 2011-2022 走看看