Spring 自定义集合实现策略

Spring 自定义集合实现策略

日常开发中,如果遇到复杂业务通常会用一个接口实现多个实现类。需要根据对应参数判断获取不同实现类。例如支付场景,根据选择支付方式,选择相应路由。如果实现类不多,通常会这样。如果实现类多了,每次新增一个实现,还需要修改路由,写的就恶心了。有没有什么好的方式可以解决呢?

if(rule1){
  return a 的实例;
}
 if(rule12){
  retuen 实现类b的实例;
}

方法一

利用Spring applicationContext
Map<String, xx> beans = applicationContext.getBeansOfType(xx.class);

然后封装工具类,根据key从map 获取对应实现类

伪代码如下

private static Map<String,xxService> serviceMap = new HashMap<>();

 Map<String, xxService> beans = applicationContext.getBeansOfType(xxService.class);
  for (xxService s : beans.values()) {
           if(serviceMap.putIfAbsent(s.type(), s) != null){
               throw new RuntimeException(s.class.getSimpleName() + " 已经存在[" + s.type() + "]类型");
           }
       }
      
或者直接注入
@Autowired
List<xxService> xxList;
通常也是使用这种方式比较多,但是感觉还是不够通用。新增了一种多态实现,还是需要改代码,存入map

方法二Spring Bean选择器模式

利用spring的注入功能,使用注解来实现依赖注入,这里自定义了列表,。其中用到了CustomCollectionEditor类。直接上代码

/**
 * @author: one
 * @date: 2024/7/27 17:29
 **/
public interface MatchBean<K> {
    boolean match(K factor);
}
/**
 * @author: one
 * @date: 2024/7/27 17:29
 **/
public interface MultiServiceFactory<E extends MatchBean<K>, K> extends List<E> {

    E getBean(K factor);

    List<E> getBeanList(K factor);
}

/**
 * @author: one
 * @date: 2024/7/27 17:29
 **/
public class MultiServiceFactoryImpl<E extends MatchBean<K>, K> extends ArrayList<E> implements MultiServiceFactory<E, K>, Serializable {

    @Override
    public E getBean(K factor) {
        Iterator<E> itr = iterator();
        while (itr.hasNext()) {
            E beanMatch = itr.next();
            if (beanMatch.match(factor)) {
                return beanMatch;
            }
        }
        return null;
    }

    @Override
    public List<E> getBeanList(K factor) {
        Iterator<E> itr = iterator();
        while (itr.hasNext()) {
            E beanMatch = itr.next();
            if (!beanMatch.match(factor)) {
                itr.remove();
            }
        }
        return this;
    }
}
MultiServiceFactoryEditor类的命名,必须是接口类MultiServiceFactory的类名+Editor组成。
super(MultiServiceFactoryImpl.class),通过CustomCollectionEditor注册了转换器。
spring-beans这个jar的BeanUtils类的findEditorByConvention方法里面,可以看到editor类名的拼接过程。targetTypeName 为工厂类的类名,editorName 为工厂类所对应的editor类名


public class MultiServiceFactoryEditor extends CustomCollectionEditor {
    public MultiServiceFactoryEditor() {
        super(MultiServiceFactoryImpl.class);
    }
}

然后在你的多态实现MatchBean接口即可,上demo

public interface Animals extends MatchBean<String> {
    String name();

    String run();

    @Override
    default boolean match(String factor) {
        return this.name().equals(factor);
    }
}

@Service
public class Dog implements Animals {
    @Override
    public String name() {
        return "dog";
    }

    @Override
    public String run() {
        return "狗跑";
    }
}

@Service
public class Cat implements Animals {
    @Override
    public String name() {
        return "cat";
    }

    @Override
    public String run() {
        return "猫跑";
    }
}

测试
@Autowired
    private MultiServiceFactory<Animals, String> multiServiceFactory;

    @PostConstruct
    public void init() {
        System.out.println(multiServiceFactory.getBean("dog").run());
        System.out.println(multiServiceFactory.getBean("cat").run());
    }

在这里插入图片描述

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值