摘要
在日常开发过程中经常需要获取类的扩展集. 即获取类的子类集 (抽象类), 或者接口实现类. 比如说状态模式中, 状态构建类, 策略模式中的, 策略构造方式. 本文介绍几种获取方式.
实现
以策略模式为例
定义了 2 种策略
- @Getter
- @AllArgsConstructor
- public enum StrategyEnum {
- APPROVE(1),
- REFUSE(2);
- private final int code;
- }
interface Handle, 实现类 ApproveHandle,RefuseHandle
方式 1 Spring 大法好
Spring 为 java web 开发提供了很多便捷, 这么刚需的需求, Spring 当然可以搞定
ListableBeanFactory 扩展了 FactoryBean, 自然能够获取 bean 的定义, 所以可以从 ApplicationContext 获取类的扩展类
- public static <T> Map<String, T> getBeansOfType(final Class<T> type) {
- if (applicationContext != null) {
- final ListableBeanFactory listableBeanFactory = applicationContext;
- return listableBeanFactory.getBeansOfType(type);
- }
- return null;
- }
方式 2 还是 Spring
Spring 提供了很多的扩展, 允许我们在初始化 bean 之前, 之后做一些自定义逻辑. 当然也可以在 Spring 装配整个过程完成后做一些注入的逻辑
- @Service
- public class InstanceBySpring implements InstanceFactory, InitializingBean {
- private static Map<StateEnum, AbstractState> map = new HashMap<>();
- private static Map<StrategyEnum, Handle> mapStrategy = new HashMap<>();
- @Autowired
- private List<AbstractState> states;
- @Autowired
- private List<Handle> handles;
- // 加载完了处理自己的逻辑
- @Override
- public void afterPropertiesSet() throws Exception {
- if (!CollectionUtils.isEmpty(states)) {
- map = states.stream().collect(Collectors.toMap(v -> v
- .getCode(), Function.identity()));
- }
- if (!CollectionUtils.isEmpty(handles)) {
- mapStrategy = handles.stream().collect(Collectors.toMap(v -> v
- .getStrateType(), Function.identity()));
- }
- }
- @Override
- public AbstractState getStateInstance(final StateEnum stateEnum) {
- return map.get(stateEnum);
- }
- @Override
- public Handle getStrategyInstance(final StrategyEnum strategyEnum) {
- return mapStrategy.get(strategyEnum);
- }
- }
方式 3 能不能不用 Spring
离了 Spring 还能不能活, 当然可以了. jdk 本身提供了扩展支持 ServiceLoader 类.
META-INF/services 配置类
- ServiceLoader.load
- public class InstanceByServiceLoader implements InstanceFactory {
- private final ServiceLoader<AbstractState> abstractStateServiceLoader = ServiceLoader.load
- (AbstractState.class);
- private final ServiceLoader<Handle> handleServiceLoader = ServiceLoader.load
- (Handle.class);
- @Override
- public AbstractState getStateInstance(final StateEnum stateEnum) {
- final List<AbstractState> result = new ArrayList<>();
- for (final AbstractState state : abstractStateServiceLoader) {
- result.add(state);
- }
- return result.stream().collect(Collectors.toMap(p -> p.getCode(), Function.identity())).get
- (stateEnum);
- }
- }
总结
这边是以接口类来介绍的, 对于接口也同样适用. 完整代码见
关注公众号 [方丈的寺院] , 第一时间收到文章的更新, 与方丈一起开始技术修行之路
来源: http://www.bubuko.com/infodetail-3105899.html