提高项目可扩展性的java spi机制运用-自定义日志框架

1. 理论参考

2. 案例提供一个简单的日志框架myslf4j

在这里插入图片描述

  • ①定义核心接口
public interface MySlf4j {

    void log(String msg);

}
  • ②定义一个默认实现(有些框架不一定给默认实现,如果用户也引入厂商的实现就报错,这里还是给个默认实现比较好)
public class MySlf4jDefaultImpl implements MySlf4j {
    @Override
    public void log(String msg) {
        System.out.println("MySlf4j的默认实现MySlf4jDefaultImpl:"+msg);
    }
}
  • ③resources/META-INF/services/下载配置这个实现,ServiceLoader#load()方法就会加载里面的实现。如上图,文件名为接口名 ,内容为实现类全路径,加载时会通过放射实例化
  • ④再写一个类来获取MySlf4j的实现进行,以便使用MySlf4j的现在
public class LogFactory {
    public static MySlf4j getFirstLogger(){
        List<MySlf4j> allImpls = getProviders();// 如果引入2个厂商实现,且在maven中优先引入B实现,则这里加载到的是B的实现(maven就近原则也许就是这么玩的)
        return allImpls.get(0);
    };

    public static MySlf4j getLastLogger(){
        List<MySlf4j> allImpls = getProviders();
        return allImpls.get(allImpls.size()-1);//要最后一个加载的
    }
    public static List<MySlf4j> getAllLogger(){ //默认及所有厂商实现都要
        return getProviders();
    }
    private static List<MySlf4j> getProviders() {
        ServiceLoader<MySlf4j> providers = ServiceLoader.load(MySlf4j.class);
        Iterator<MySlf4j> it = providers.iterator();
        List<MySlf4j> allImpls = new ArrayList<>();
        while (it.hasNext()) {
            allImpls.add(it.next());
        }
        return allImpls;
    }

    ;
}

3.测试框架

就改项目mvn install到本地maven仓库,再在业务项目引入my-slf4j进行日志打印

<dependency>
   <groupId>com.xxx</groupId>
    <artifactId>my-slf4j</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

测试my-slf4j
在这里插入图片描述

4.厂商jwolf实现

  • ①厂商实现需要先引入my-slf4j定义的接口
<dependency>
   <groupId>com.xxx</groupId>
    <artifactId>my-slf4j</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
  • ②自己实现MySlf4j接口
public class JwolfMySlf4j implements MySlf4j {
    @Override
    public void log(String msg) {
        System.out.println("Jwolf厂商实现JwolfMySlf4j:"+msg);
    }
}
  • ③注册实现,注意文件名仍然为com.xx.MySlf4j 实现写Jwolf自己的实现的类全路径
    在这里插入图片描述

5.业务项目同时引入my-slf4j,及其厂商实现jwolfmyslf4j,且my-slf4j先引入,则优先加载的是my-slf4j

在这里插入图片描述

在这里插入图片描述

6.交换my-slf4j,及其厂商实现jwolfmyslf4j引入顺序,providers加载顺序也变了

在这里插入图片描述
在这里插入图片描述
总结

  • 本案例利用spi机制实现了类似原生slf4j的日志框架,my-slf4j具有可扩展性,具体厂商实现具有可插拔性
  • 多个实现时的加载顺序有点类似maven的就近原则,最短路径原则
  • 使用该机制可实现市面上有些框架类似的plugin就可以利用spi实现,插件制造者实现统一的接口,并将包放入plugin下吗,serviceload就可加载。只是这些plugin在项目外,需要配置外置jar包加载路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值