美文网首页
一种简洁的Spring Bean选择器模式

一种简洁的Spring Bean选择器模式

作者: bailiyi | 来源:发表于2019-12-29 14:45 被阅读0次

    作用

    在日常开发中,我们常常会遇到一个接口有多个实现类时,需要选择合适的实现类的情况。

    最简单的方法是写一个选择器,用if-else来判断使用哪个实现类的实例,比如:

    if(条件1){
      return 实现类a的实例;
    }else if(条件2){
      retuen 实现类b的实例;
    }
    

    然而这种方法不符合开闭原则(OCP),如果再添加一个实现类,那么选择器的代码也需要再加一个else if。

    所以,在参考了同事及网上的一些代码后,我整理出了一种简洁的、符合设计原则的实现方式。

    一种更好的选择器:工具类

    这种选择器使用了策略模式,并且利用了Spring的自动注入特性。

    首先,我们需要提供4个工具类:

    public interface MatchingBean<K> {
        boolean matching(K factor);
    }
    
    public interface MyFactoryList<E extends MatchingBean<K>, K> extends List<E> {
        E getBean(K factor);
        List<E> getBeanList(K factor);
    }
    
    public class MyFactoryArrayList<E extends MatchingBean<K>, K> extends ArrayList<E>
            implements MyFactoryList<E, K>, Serializable {
        @Override
        public E getBean(K factor) {
            Iterator<E> itr = iterator();
            while (itr.hasNext()) {
                E beanMatch = itr.next();
                if (beanMatch.matching(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.matching(factor)) {
                    itr.remove();
                }
            }
            return this;
        }
    }
    
    public class MyFactoryListEditor extends CustomCollectionEditor {
        public MyFactoryListEditor() {
            super(MyFactoryArrayList.class);
        }
    }
    

    一种更好的选择器:使用示例

    假设我们有个购物接口,有淘宝和京东两个实现。

    那么就让购物接口继承MatchingBean,代码如下:

    public interface BuyService extends MatchingBean<String> {
        public String goShopping();
    }
    

    然后在实现类里实现matching方法,代码如下:

    @Service
    public class JingdongService  implements BuyService {
    
        @Override
        public String goShopping() {
            return "Shopping in Jd";
        }
    
        @Override
        public boolean matching(String factor) {
            return "jd".equals(factor);
        }
    }
    
    @Service
    public class TaobaoService implements BuyService {
    
        @Override
        public String goShopping() {
            return "Shopping in Taobao";
        }
    
        @Override
        public boolean matching(String factor) {
            return "taobao".equals(factor);
        }
    }
    

    最后,咱们写个测试类,看下选择器的使用方法:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestMyBeanUtil {
    
        @Autowired
        MyFactoryList<BuyService,String> factoryList;
    
        @Test
        public void testOne(){
            BuyService shop = factoryList.getBean("jd");
            System.out.println(shop.goShopping());
        }
    }
    

    参考文献

    https://my.oschina.net/guanhe/blog/1821060
    系列文章总目录:https://mp.weixin.qq.com/s/56JgXLArTAEDj1f3y4arLA

    相关文章

      网友评论

          本文标题:一种简洁的Spring Bean选择器模式

          本文链接:https://www.haomeiwen.com/subject/ukvyoctx.html