实例介绍基于项目依赖包选择具体实现类

最近遇到一个需求场景,开源的工具包,新增了一个高级特性,会依赖json序列化工具,来做一些特殊操作;但是,这个辅助功能并不是必须的,也就是说对于使用这个工具包的业务方而言,正常使用完全不需要json相关的功能;如果我强引用某个json工具,一是对于不适用高级特性的用户而言没有必要;二则是我引入的json工具极有可能与使用者的不一致,会增加使用者的成本

因此我希望这个工具包对外提供时,并不会引入具体的json工具依赖;也就是说maven依赖中的<scope>设置为provided;具体的json序列化的实现,则取决于调用方自身引入了什么json工具

那么可以怎么实现上面这个方式呢?

1. 任务说明

上面的简单的说了一下我们需要做的事情,接下来我们重点盘一下,我们到底是要干什么

核心诉求相对清晰

  1. 不强引入某个json工具
  2. 若需要使用高级特性,则直接使用当前环境中已集成的json序列化工具;若没有提供,则抛异常,不支持

对于上面这个场景,常年使用Spring的我们估计不会陌生,Spring集成了很多的第三方开源组件,根据具体的依赖来选择最终的实现,比如日志,可以是logback,也可以是log4j;比如redis操作,可以是jedis,也可以是lettuce

那么Spring是怎么实现的呢?

2.具体实现

在Spring中有个注解名为ConditionalOnClass,表示当某个类存在时,才会干某些事情(如初始化bean对象)

它是怎么是实现的呢?(感兴趣的小伙伴可以搜索一下,或者重点关注下 SpringBootCondition 的实现)

这里且抛开Spring的实现姿势,我们采用传统的实现方式,直接判断是否有加载对应的类,来判断有没有引入相应的工具包

如需要判断是否引入了gson包,则判断ClassLoader是否有加载com.google.gson.Gson

public static boolean exist(String name) {
    try {
        return JsonUtil.class.getClassLoader().loadClass(name) != null;
    } catch (Exception e) {
        return false;
    }
}

上面这种实现方式就可以达到我们的效果了;接下来我们参考下Spring的ClassUtils实现,做一个简单的封装,以判断是否存在某个类

// 这段代码来自Spring
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Spring
 */
public abstract class ClassUtils {
    private static final Map<String, Class<?>> primitiveTypeNameMap = new HashMap(32);
    private static final Map<String, Class<?>> commonClassCache = new HashMap(64);

    private ClassUtils() {
    }

    public static boolean isPresent(String className) {
        try {
            forName(className, getDefaultClassLoader());
            return
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值