二七零零 2021-10-11 23:53 采纳率: 66.7%
浏览 119
已结题

一个接口多个实现类,怎么通过yml配置和工厂模式动态获取对应的实现类?

一个接口多个实现类,怎么通过yml配置和工厂模式动态获取对应的实现类?
我们主管跟我说,自定义一个注解,通过工厂来包装,最后只需要在yml里面配置参数,需要获取那个实现类就配置一下,但是做到下面了,就是不明白主管跟我说的到底要怎么做,
主管还提到了用ApplicationContext通过注解获取注解类的方法,
但是始终自己连贯不起来,请求解惑。非常感谢!!
我最终想实现的是,工厂类不变,如果我要新增一个DImpl实现类,直接在yml里面配置参数对应的值D,新增D实现类,这样业务代码里面就可以通过工厂来得到D的实现类,调D中的方法

// 一个接口
public interface SendSmsService {
    RetData<SmsageVO> sendSmsMessage(SmsInVO smsInVO);
}

A实现类
@Service
@Slf4j
public class ASendSmsServiceImpl implements SendSmsService {
    @Override
    public RetData<SmsageVO> sendSmsMessage(SmsInVO smsInVO) {........}
 
B实现类
@Service
@Slf4j
public class BSendSmsServiceImpl implements SendSmsService {
    @Override
    public RetData<SmsageVO> sendSmsMessage(SmsInVO smsInVO) {........}
 
C实现类
@Service
@Slf4j
public class CSendSmsServiceImpl implements SendSmsService {
    @Override
    public RetData<SmsageVO> sendSmsMessage(SmsInVO smsInVO) {........}
 


定义一个工厂类
@Component
public class SmsFactory {
    private static SendSmsService sendSmsService;
    @Autowired
    private static ASendSmsServiceImpl aSendSmsService;
    @Autowired
    private static BSendSmsServiceImpl BSendSmsService;
    @Autowired
    private static CSendSmsServiceImpl cSendSmsService;

    @Value("${message.center.smsOperator}")
    static String smsOperator;

    @Autowired
    static Map<String,SendSmsService> serviceMap;


    public static  SendSmsService getSmsServiceImpl() {
        serviceMap.put("A",aSendSmsService);
        serviceMap.put("B",bSendSmsService);
        serviceMap.put("C",cSendSmsService);
        SendSmsService smsService = serviceMap.get(smsOperator);
        return smsService;

       /* if (smsOperator == null) {
            return null;
        }
        SendSmsService sendSmsService = null;
        switch (smsOperator) {
            case "A":
                sendSmsService = new ASendSmsServiceImpl();
                break;
            case "B":
                sendSmsService = new BSendSmsServiceImpl();
                break;
            case "C":
                sendSmsService = new CSendSmsServiceImpl();
                break;
            default:
                  break;
        }
        return sendSmsService;*/
    }



  • 写回答

3条回答 默认 最新

  • zcl_1991 2021-10-12 09:19
    关注

    首先在实现类上面要加入注解 @Component("aImpl")(其他注解也行,主要是让spring去管理),设置好名字;

    然后再工厂里面直接用一个map接收:
    @Autowired
    private Map<String,SendSmsService> serviceMap;

    这个map里面就包含了所有的实现类,key是实现类注解上面定义的名称,value就是对应的实现类;
    这下想怎么使用都行了。
    如果需要在配置里面指定使用某一个实现类,工厂里面获取配置,map.get() 就行了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 影流之祖 2021-10-12 10:22
    关注

    这个场景有点类似于jdbc啊 配置文件写的mysql就连mysql 写的oracle就连oracle 为什么不参考一下jdbc的实现呢 他可不是把所有的实现类写到一起 而是在调用层只写接口 实现写到对应的驱动里 比如你要连mysql那就引入mysql的驱动 如果把所有实现类写到一起 看你的描述的话是我配置的谁使用谁 那么同一时间其他的实现类相当于占jar包的垃圾文件 是没有必要的 建议分模块实现 再抽象一下
    如果业务场景让你不得不写到一起的话 工厂可以实现beanfacrotyAware接口来获取spring的beanfactory进一步获取bean,和楼上说的也差不多

    评论
  • a1767028198 2021-10-12 08:57
    关注

    @Autowired
    private static ASendSmsServiceImpl aSendSmsService;
    @Autowired
    private static BSendSmsServiceImpl BSendSmsService;
    @Autowired
    private static CSendSmsServiceImpl cSendSmsService;
    这个肯定不行,你这写死了,从BeanFactory或者ApplicationContext获取bean 直接返回就行了,
    至于获取类注解,感觉没必要,既然你是同一个类的实现,又交给容器管理了,再加注解作用就没有了

    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月23日
  • 已采纳回答 10月15日
  • 修改了问题 10月12日
  • 创建了问题 10月11日

悬赏问题

  • ¥15 我不明白为什么c#微软的官方api浏览器为什么不支持函数说明的检索,有支持检索函数说明的工具吗?
  • ¥15 ORBSLAM2框架跑ICL-NUIM数据集
  • ¥15 在我想检测ros是否成功安装时输入roscore出现以下
  • ¥30 老板让我做一个公司的投屏,实时显示日期,时间,安全生产的持续天数,完全没头绪啊
  • ¥15 Google Chrome 所有页面崩溃,三种解决方案都没有解决,我崩溃了
  • ¥20 使用uni-app发起网络请求,获取重定向302返回的cookie
  • ¥20 手机外部浏览器拉起微信小程序支付 (相关搜索:微信小程序)
  • ¥20 怎样通过一个网址找到其他同样模版的网址
  • ¥30 XIAO esp32c3 读取FDC2214的数据
  • ¥15 在工控机(Ubuntu系统)上外接USB蓝牙硬件进行蓝牙通信