摘要

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

实现

以策略模式为例

定义了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

关注公众号【方丈的寺院】,第一时间收到文章的更新,与方丈一起开始技术修行之路

java基础(1)-几种获取类的扩展方式的更多相关文章

  1. Java基础-类加载机制与自定义类Java类加载器(ClassLoader)

    Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...

  2. Java基础-DBCP连接池(BasicDataSource类)详解

    Java基础-DBCP连接池(BasicDataSource类)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程 ...

  3. 流式思想概述和两种获取Stream流的方式

    流式思想概述 整体来看,流式思想类似于工厂车间的生产流水线 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个模型步骤方案,然后再按照方法去执行他 这张图中展示 ...

  4. SpringMVC 02: SpringMVC响应get和post请求 + 5种获取前端数据的方式

    响应get和post请求 SpringMVC中使用@RequestMapping注解完成对get请求和post请求的响应 项目结构和配置文件与SpringMVC博客集中的"SpringMVC ...

  5. spring mvc中几种获取request对象的方式

    在使用spring进行web开发的时候,优势会用到request对象,用来获取访问ip.请求头信息等 这里收集几种获取request对象的方式 方法一:在controller里面的加参数 public ...

  6. Js之Dom学习-三种获取页面元素的方式、事件、innerText和innerHTML的异同

    一.三种获取页面元素的方式: getElementById:通过id来获取 <body> <input type="text" value="请输入一个 ...

  7. Java基础——数组应用之StringBuilder类和StringBuffer类

    接上文:Java基础——数组应用之字符串String类 一.StringBuffer类 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和 ...

  8. Java基础教程(12)--深入理解类

    一.方法的返回值   当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...

  9. Java反射学习-1 - 反射获取类的属性,方法,构造器

    新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...

随机推荐

  1. Delphi 获取外部程序句柄与发送消息

    --记录下来备以后用 [打开外部程序.消息.句柄],技术有限,希望不要误人子弟了. 源码unit Unit1; interface uses Windows, Messages, SysUtils, ...

  2. Customize Acrylic Brush in UWP Applications(在UWP中自定义亚克力笔刷)

    原文 Customize Acrylic Brush in UWP Applications(在UWP中自定义亚克力笔刷) Windows 10 Fall Creators Update(Build ...

  3. Method of packet transmission from node and content owner in content-centric networking

    A method of transmitting a content reply packet from a content owner in content-centric networking ( ...

  4. Android TV开发总结(七)构建一个TV app中的剧集列表控件

    原文:Android TV开发总结(七)构建一个TV app中的剧集列表控件 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必转载 ...

  5. 对XAML进行编辑的辅助类(XamlHelper)

    原文:对XAML进行编辑的辅助类(XamlHelper) // XamlHelper.cs// --------------------------------------------// 对XAML ...

  6. Jconsole使用实例解说

    Jconsole是jdk自带的一套java虚拟机执行状况监视器,它能够用来监控虚拟机的内存,线程,cpu使用情况以及相关的java进程相关的MBean,主界面例如以下: 图1 怎样连接被监控的Java ...

  7. 上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片

    原文:上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片 我们知道,如果网站上传图片时,如果用户上传的是CMYK图片,那么在网站上将是无法显示的,通常的现象是出现一个红叉.下面使用将Ima ...

  8. Monthly Expense

    Problem Description Farmer John is an astounding accounting wizard and has realized he might run out ...

  9. MySQL第五个学习笔记 该数据表的操作

    MySQL在创建表,创建.frm文件保存表和列定义.索引存储在一个.MYI(MYindex)且数据存储在有.MYD(MYData)扩展名的文件里.   一.用SHOW/ DESCRIBE语句显示数据表 ...

  10. 1407251735-hd-美素数.cpp

    #include<stdio.h> int s1[1005000],s2[1005000]; //如果main该阵列外部函数中定义,全局变量的数组,自己主动初始化数组0: //在main里 ...