zoukankan      html  css  js  c++  java
  • java基础(1)-几种获取类的扩展方式

    摘要

    在日常开发过程中经常需要获取类的扩展集。即获取类的子类集(抽象类),或者接口实现类。比如说状态模式中,状态构建类,策略模式中的,策略构造方式。本文介绍几种获取方式。

    实现

    以策略模式为例
    定义了2种策略

    @Getter
    @AllArgsConstructor
    public enum StrategyEnum {
        APPROVE(1),
        REFUSE(2);
        private final int code;
    }
    

    interface Handle,实现类ApproveHandleRefuseHandle

    方式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类。

    1. META-INF/services配置类
    2. 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);
        }
    }
    

    总结

    这边是以接口类来介绍的,对于接口也同样适用。完整代码见github

    关注公众号【方丈的寺院】,第一时间收到文章的更新,与方丈一起开始技术修行之路
    在这里插入图片描述

  • 相关阅读:
    TextBox 只有下划线
    can't find web control library(web控件库)
    DropDownListSalesAC”有一个无效 SelectedValue,因为它不在项目列表中。
    IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
    如何打印1px表格
    CSS控制打印 分页
    Virtual Server could not open its emulated Ethernet switch driver. To fix this problem, reenable the Virtual Server Emulated Et
    Xml中SelectSingleNode方法中的xpath用法
    热带水果莫入冰箱?水果存放冰箱大法
    探索Asp.net的Postback机制
  • 原文地址:https://www.cnblogs.com/stoneFang/p/11099576.html
Copyright © 2011-2022 走看看