Java SPI 机制,主要是类加载器反双亲委派的实现(第三方包不在指定jdk路径,一般类加载器无法加载,需要特殊的ContextClassLoader加载以便使用)。本次将对 SPI机制进行详解,并结合案例介绍其在实际场景中具体使用。
提示:以下是本篇文章正文内容,案例仅供对比参考
鉴于目前实际项目涉及范围,总结出的常见应用场景。
3.1 接口权限定文件名方式
即在resource文件下创建META/services/目录,并在此目录下新建文件,文件名称为接口类权限定文件名,如 com.lgy.spidemo.serviceway.SpiService。(不好理解就是接口类的package地址 + 接口类名)
使用场景一:
package com.lgy.spidemo.serviceway; /** * @description: 考勤接口 **/ public interface AttendanceService { void pullAttendanceInfos(); }
/** * @description: 职能部门考勤实现 **/ public class FunctionAttendanceServiceImpl implements AttendanceService { @Override public void pullAttendanceInfos() { System.out.println(" FunctionAttendanceService implements ..."); // 逻辑忽略 } }
/** * @description: 销售部门考勤实现 **/ public class SaleAttendanceServiceImpl implements AttendanceService { @Override public void pullAttendanceInfos() { System.out.println(" SaleAttendanceService implements ..."); // 逻辑忽略 } }
/** * 1、项目的\src\main\resources\下创建\META-INF\services目录 * 2、META-INF\services的目录下再增加一个配置文件,这个文件必须以接口的全限定类名保持一致 (com.lgy.spidemo.service.SpiService) * 3、在配置文件中写入具体实现类的全限定类名,如有多个便换行写入 com.lgy.spidemo.service.impl.SaleAttendanceServiceImpl com.lgy.spidemo.service.impl.FunctionAttendanceServiceImpl **/ public class AttendanceServiceTest { public static void main(String[] args) { ServiceLoaderservices = ServiceLoader.load(AttendanceService.class); // 省略判断人员部门类型逻辑 // 测试输出结果,展示实现接口已加载 for (AttendanceService service : services) { service.pullAttendanceInfos(); } } }
// 两个实现类均被加载成功,在实际使用时,可根据需要去调用不同的实现。 FunctionAttendanceService implements ... SaleAttendanceService implements ....
实现类不要标注任何注解,不然Spring在初始化过程中扫描并加载,无法测试。
结合场景一分析:
3.2 spring.factories方式
使用场景二
代码如下:
package com.lgy.spidemo.factoriesway; import org.springframework.boot.autoconfigure.AutoConfigurationImportEvent; import org.springframework.boot.autoconfigure.AutoConfigurationImportListener; /** * @description: 自动配置swagger **/ public class SwaggetAutoConfiguration { public SwaggetAutoConfiguration() { System.out.println(" SwaggetAutoConfiguration init ..."); } // 配置内容省略 } /** * @description: 自动配置dataway **/ public class DataWayAutoConfiguration { public DataWayAutoConfiguration() { System.out.println(" DataWayAutoConfiguration init ..."); } // 配置内容省略 } /** * resource/META-INFO/spring.factories 文件内容 * * org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.lgy.spidemo.factoriesway.SwaggetAutoConfiguration * 输出结果:SwaggetAutoConfiguration init ... **/
结合场景二分析:
本次讲解的两种方式均是基于SPI机制,可见是多么受开发追捧。当然,还有很多种实现方式,我个人觉得最主要的还是能够在自己的掌控范围内去使用,毕竟有问题可以通过自己的学习理解去解决。
最后说一句,没有更好的技术知识,只有更适合的技术应用,结合实际,检出真理。