目录
  • 前言
  • 一、获取接口的所有实现类
    • 1、枚举
    • 2、业务接口
      • 2.1 实现类
    • 3、ApplicationContextAware接口实现类
      • 4、获取到所有实现类使用

      前言

      有时候,根据业务逻辑的需求,需要获取到某个接口的所有实现类,然后根据业务类型来执行不同的实现类方法。有点类似策略模式。

      • 如果没有用到 Spring的话,可以使用 ServiceLoaderl类JDK自带的一个类加载器(其他框架的SPI机制也是可以实现)。
      ServiceLoader<MyInterface> loader = ServiceLoader.load(接口名.class);

      如果接口的所有实现类均被 Spring托管了。那么我们可以从Spring的IOC容器中可以很简单的获取这些实现类。

      以上两种方式,实现的功能都是一样的,实现方式不同,底层用的技术一样的,都是反射。

      下面我们基于 Spring管理的 bean中来获取接口的所有实现类。

      可以直接使用 Spring的 @Autowired注解。也可以使用 ApplicationContextAware接口来获取并管理所有实现类。

      一、获取接口的所有实现类

      1、枚举

      这个枚举根据业务自行创建,可有可无。

      public enum XxxTypeEnum {
          XXX_1("code1", "xxx1业务"),
          XXX_2("code2", "xxx2业务"),
          ;
          private String code;
          private String desc;
          XxxTypeEnum(String code, String desc) {
              this.code = code;
              this.desc = desc;
          }
          public String getCode() {
              return code;
          }
          public void setCode(String code) {
              this.code = code;
          }
          public String getDesc() {
              return desc;
          }
          public void setDesc(String desc) {
              this.desc = desc;
          }
      
      }

      2、业务接口

      public interface IXxxService {
      
          /**
           *是否支持
           * @param xxxTypeEnum
           * @return
           */
          boolean isSupport(XxxTypeEnum xxxTypeEnum);
      
          /**
           * 拼接字符串业务方法
           *
           * @param a
           * @param b
           * @return
           */
          String spliceStr(String a, String b);
      }

      2.1 实现类

      1)Xxx001ServiceImpl

      @Service
      public class Xxx001ServiceImpl implements IXxxService {
          @Override
          public boolean isSupport(XxxTypeEnum xxxTypeEnum) {
              return XxxTypeEnum.XXX_1.equals(xxxTypeEnum);
          }
          @Override
          public String spliceStr(String a, String b) {
              return a + "--Xxx001ServiceImpl--" + "b";
          }
      }

      2)Xxx002ServiceImpl

      @Service
      public class Xxx002ServiceImpl implements IXxxService {
          @Override
          public boolean isSupport(XxxTypeEnum xxxTypeEnum) {
              return XxxTypeEnum.XXX_2.equals(xxxTypeEnum);
          }
          @Override
          public String spliceStr(String a, String b) {
              return a + "--Xxx002ServiceImpl--" + "b";
          }
      
      }

      3、ApplicationContextAware接口实现类

      获取到所有实现类,然后根据业务管理所有实现类。

      @Component
      public class XxxServiceLocator implements ApplicationContextAware {
      	/**
      	 * 存储 IXxxService接口的所有实现类
      	 */
      	private Map<String, IXxxService> xxxServiceMap;
      	private List<IXxxService> xxxServiceList;
      	@Override
      	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      		// 通过上下文,根据接口类型返回相应的所有实现类bean
      		xxxServiceMap = applicationContext.getBeansOfType(IXxxService.class);
      		xxxServiceList = new ArrayList<>(xxxServiceMap.values());
      	}
      	/**
      	 * 获取所有实现类
      	 *
      	 * @return
      	 */
      	public Map<String, IXxxService> getAllMap() {
      		return xxxServiceMap;
      	}
      
      	/**
      	 * 通过名称获取某个实现类
      	 *
      	 * @param beanName
      	 *            bean名字
      	 * @return
      	 */
      	private IXxxService getByName(String beanName) {
      		return xxxServiceMap.get(beanName);
      	}
      
      	/**
      	 * 获取所有实现类
      	 *
      	 * @return
      	 */
      	public List<IXxxService> getAllList() {
      		return xxxServiceList;
      	}
      
      	/**
      	 * 根据枚举获取某个实现类
      	 *
      	 * @param xxxTypeEnum
      	 * @return
      	 */
      	public IXxxService get(XxxTypeEnum xxxTypeEnum) {
      		IXxxService xxxService = xxxServiceList.stream().filter(s -> s.isSupport(xxxTypeEnum))
      				.collect(Collectors.toList()).get(0);
      		return xxxService;
      	}
      
      }

      4、获取到所有实现类使用

      @RestController
      @RequestMapping(value = "/xxx")
      public class XxxController {
          /**
           * 方式1:直接使用spring依赖注入注解
           */
          @Autowired
          private Map<String, IXxxService> xxxServiceMap;
      
          /**
           * 方式2:直接使用spring的依赖注入注解
           */
          @Autowired
          private List<IXxxService> xxxServiceList;
      
          /**
           * 方式3:借助spring的ApplicationContextAware
           */
          @Autowired
          private XxxServiceLocator xxxServiceLocator;
      
          /**
           * 获取到所有实现类使用
           *
           */
          @RequestMapping(value = "/getAll", method = RequestMethod.GET)
          public void getAll() {
              String a = "asasa";
              String b = "bnbnb";
              Map<String, IXxxService> allMap = xxxServiceLocator.getAllMap();
              List<IXxxService> allList = xxxServiceLocator.getAllList();
      
              System.out.println("allMap              --->" + allMap);
              System.out.println("xxxServiceMap       --->" + xxxServiceMap);
              System.out.println("allList             --->" + allList);
              System.out.println("xxxServiceList      --->" + xxxServiceList);
              for (IXxxService iXxxService : xxxServiceList) {
                  System.out.println("xxxServiceList执行结果  ---> " + iXxxService.spliceStr(a, b));
              }
              IXxxService iXxxService = xxxServiceLocator.get(XxxTypeEnum.XXX_1);
              System.out.println("XxxEnum.XXX_1执行结果  ---> " + iXxxService.spliceStr(a, b));
              iXxxService = xxxServiceLocator.get(XxxTypeEnum.XXX_2);
              System.out.println("XxxEnum.XXX_2执行结果  ---> " + iXxxService.spliceStr(a, b));
      
          }
      }

      Java SpringBoot 获取接口实现类汇总

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。