spring自定义集合,实现策略模式

在学习spring选择器的时候,找到了这篇文章:

https://zhuanlan.zhihu.com/p/100035474

里面用到了spring的注入功能,使用注解来实现依赖注入,这里自定义了列表,然后把两个service注入进去。其中用到了CustomCollectionEditor类,这个类继承了jdk的PropertyEditorSupport类。PropertyEditorSupport类是用来实现属性值的转换功能。比如说处理xml文件里面字符串到java对象的转换。同类型的service注册到map里面去,这里实现的是map到list的转换。如果不加转换,会报org.springframework.beans.factory.UnsatisfiedDependencyException异常。详情见参考。

现在说说当前这个转换。参考代码如下:

public interface MatchingBean<K> {
    boolean matching(K factor);
}

通过matching方法来匹配具体的bean对象,bean要实现这个接口。

public interface MyFactoryList<E extends MatchingBean<K>, K> extends List<E> {
    E getBean(K factor);

    List<E> getBeanList(K factor);
}

通过getBean方法来获取bean对象。

MyFactoryList的实现类:

public class MyFactoryArrayList<E extends MatchingBean<K>, K> extends ArrayList<E> implements MyFactoryList<E, K>, Serializable {
    @Override
    public E getBean(K factor) {
        for (E beanMatch : this) {
            if (beanMatch.matching(factor)) {
                return beanMatch;
            }
        }
        return null;
    }

    @Override
    public List<E> getBeanList(K factor) {
        removeIf(beanMatch -> !beanMatch.matching(factor));
        return this;
    }
}
public class MyFactoryListEditor extends CustomCollectionEditor {
    public MyFactoryListEditor() {
        super(MyFactoryArrayList.class);
    }
}

MyFactoryListEditor类的命名,必须是接口类MyFactoryList的类名+Editor组成。
super(MyFactoryArrayList.class)通过CustomCollectionEditor注册了转换器。
spring-beans这个jar的BeanUtils类的findEditorByConvention方法里面,可以看到editor类名的拼接过程。targetTypeName 为工厂类的类名,editorName 为工厂类所对应的editor类名。代码如下:

String targetTypeName = targetType.getName();
String editorName = targetTypeName + "Editor";
public interface BuyService extends MatchingBean<String> {
    String goShopping();
}

goShopping是业务接口。

下面是两个业务的实现代码:

@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);
    }
}

测试代码:

@SpringBootTest
class SelectorApplicationTests {

    @Autowired
    MyFactoryList<BuyService,String> factoryList;

    @Autowired
    List<BuyService> buyServices;

    @Test
    void contextLoads() {
        BuyService shop = factoryList.getBean("jd");
        System.out.println(shop.goShopping());
        System.out.println(buyServices.size());
    }

}

factoryList通过@Autowired实现依赖注入,buyServices本身是list容器,spring已经内置了这个转换。

参考:

https://blog.csdn.net/zhonglin_li/article/details/51571093
https://zhuanlan.zhihu.com/p/100035474

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值