一个接口多个实现类的实现 指定

时间:2022-05-22 01:15:48

问题:一个接口有多个实现类,在用spring的@Autowired 进行注入的时候,那么service选的是哪一个实现?现在我们用工厂的方式进行实现

1.定义一个接口

package com.example.test.service;


import com.example.test.constant.ExecutorServiceTypeEnum;

public interface EventExecutorService {
    /**
     * 事件准备
     */
    void eventPrepare();

    /**
     * 获取对应事件的枚举
     * @return
     */
    ExecutorServiceTypeEnum getExecutorTypeEnum();

}

2.定义接口的三个实现类 通过 getExecutorTypeEnum() 方法确定身份
第一个实现类 EventExecutorServiceImpl

package com.example.test.service.impl;

import com.example.test.constant.ExecutorServiceTypeEnum;
import com.example.test.service.EventExecutorService;
import org.springframework.stereotype.Service;

/**
 * @Author
 */
@Component

public class EventExecutorServiceImpl implements EventExecutorService {
    @Override
    public void eventPrepare() {
        System.out.println(" EventExecutorServiceImpl1:  eventPrepare");
    }

    @Override
    public ExecutorServiceTypeEnum getExecutorTypeEnum() {
        return ExecutorServiceTypeEnum.EVENT_EXECUTOR;
    }
}

第二个实现类 EventExecutorServiceImpl1

package com.example.test.service.impl;

import com.example.test.constant.ExecutorServiceTypeEnum;
import com.example.test.service.EventExecutorService;
import org.springframework.stereotype.Component;

/**
 * @Author
 */
@Component
public class EventExecutorServiceImpl1 implements EventExecutorService {
    @Override
    public void eventPrepare() {
        System.out.println(" 1->>>>>>>>>>>>EventExecutorServiceImpl1:  eventPrepare");
    }

    @Override
    public ExecutorServiceTypeEnum getExecutorTypeEnum() {
        return ExecutorServiceTypeEnum.EVENT_EXECUTOR1;
    }

}

第三个实现类 EventExecutorServiceImpl2

package com.example.test.service.impl;

import com.example.test.constant.ExecutorServiceTypeEnum;
import com.example.test.service.EventExecutorService;
import org.springframework.stereotype.Component;

/**
 * @Author
 */
@Component
public class EventExecutorServiceImpl2 implements EventExecutorService {


    @Override
    public void eventPrepare() {
        System.out.println(" 2->>>>>>>>>>>>EventExecutorServiceImpl2:  eventPrepare");
    }

    @Override
    public ExecutorServiceTypeEnum getExecutorTypeEnum() {
        return ExecutorServiceTypeEnum.EVENT_EXECUTOR2;
    }
}

3.定义一个枚举类 ExecutorServiceTypeEnum
实现类通过枚举确定唯一的身份

package com.example.test.constant;


public enum ExecutorServiceTypeEnum {

    /**
     * 按 EventExecutorServiceImpl 执行
     */
    EVENT_EXECUTOR("eventExecutorServiceImpl", "EventExecutorServiceImpl执行"),
    /**
     * 按 EventExecutorServiceImpl1 执行
     */
    EVENT_EXECUTOR1("eventExecutorServiceImpl1", "EventExecutorServiceImpl1执行"),
    /**
     * 按 EventExecutorServiceImpl2 执行
     */
    EVENT_EXECUTOR2("eventExecutorServiceImpl2", "EventExecutorServiceImpl2执行");

    private String name;

    private String desc;

    ExecutorServiceTypeEnum(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }
}

4.定义一个工厂类 EventExecutorFactory
通过 getExecutorService() 方法 遍历 @AutoWIred注入的 EventExecutorService 并和传入的参数进行比较 确认用哪个实现类

package com.example.test.service;

import com.example.test.constant.ExecutorServiceTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author 
 * @
 */
@Component
public class EventExecutorFactory {

    @Autowired
    List<EventExecutorService> executorServices;

    public EventExecutorService getExecutorService(ExecutorServiceTypeEnum executeType){
        for(EventExecutorService eventExecutor: executorServices){
            if(eventExecutor.getExecutorTypeEnum() == executeType){
                return eventExecutor;
            }
        }
        return null;
    }
}

5.定义一个 定时任务启动类 EventExeQuartz

package com.example.test.quartz;

import com.example.test.constant.ExecutorServiceTypeEnum;
import com.example.test.service.EventExecutorFactory;
import com.example.test.service.EventExecutorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Component
public class EventExeQuartz {

    @Autowired
    private EventExecutorFactory executorFactory;

    
    @Scheduled(cron = "0/5 * * * * ?")
    public void read() {
        EventExecutorService executorService = executorFactory.getExecutorService(ExecutorServiceTypeEnum.EVENT_EXECUTOR);
        EventExecutorService executorService1 = executorFactory.getExecutorService(ExecutorServiceTypeEnum.EVENT_EXECUTOR1);
        EventExecutorService executorService2 = executorFactory.getExecutorService(ExecutorServiceTypeEnum.EVENT_EXECUTOR2);

        executorService.eventPrepare();
        executorService1.eventPrepare();
        executorService2.eventPrepare();
    }
}

结果:每5秒

 EventExecutorServiceImpl1:  eventPrepare
 1->>>>>>>>>>>>EventExecutorServiceImpl1:  eventPrepare
 2->>>>>>>>>>>>EventExecutorServiceImpl2:  eventPrepare
 EventExecutorServiceImpl1:  eventPrepare
 1->>>>>>>>>>>>EventExecutorServiceImpl1:  eventPrepare
 2->>>>>>>>>>>>EventExecutorServiceImpl2:  eventPrepare

注意:
1.这里的工厂类和实现类都要交给spring去管理 @Component注解
2.当一个对象使用过关键字new时,它是不能被Spring所管理的 所以这里使用定时任务的方式执行任务