java-神秘的SPI机制

文章详细介绍了Java的SPI(ServiceProviderInterface)机制,包括其工作原理、如何通过反射加载类,以及如何编写自己的SPI机制。通过一个简单的例子展示了如何解析配置文件并实例化对象,强调了SPI在中间件扩展中的作用。
摘要由CSDN通过智能技术生成

致敬大师,致敬未来的你
生命不止,学习不息,运动不息
Life does not stop, learning does not stop, movement does not stop

总述

SPI机制,全名 Service Provider Interface
希望看完这篇文章之后,再看java的SPI机制就可以一路通畅了
学过反射的同学都知道,java有一种类的加载机制,比如说有一个com.bean.Person类,要获取它的Class对象,可以通过以下代码获取

Class<Person> clzz = Class.forname("com.bean.Person");

SPI机制

只要知道以上的反射,就不难理解SPI机制
SIP机制其实分为以下两个步骤:
SPI机制
没错,你没看错,就是这么简单,但是,为什么要搞这么复杂呢,直接Class.forname加载不就行了么,接下来就解答:
在各种中间件中,有很多需要扩展的点,比如netty、spring boot、dubbo
但是中间件不知道你扩展的全类名叫什么,这就是一种扩展机制
但是,又说,spring中的注解方式不也是一种方式么,对的,这两种方式都行,还有XML方式、等等,主要是看中间件喜欢那种方式

解析文件

以下是中间件中常用的获取项目下文件的方法,也是mybatis、spring、等等中间件常用的
filePath为项目的相对目录

URL resource = Thread.currentThread().getContextClassLoader().getResource(filePath);

生成对象

Class<?> clz = Class.forName(className);
Object obj = clz.newInstance();

总结

这么简单
对,你没看错,就是这么简单
SPI机制就是 解析文件 + 生成对象
那么上面两步合下来就是下边:

编写自己的SPI机制

Person接口

package com.spi;

public interface Person {
	public String getName();
}

YeollowPerson实现类

package com.spi;

public class YeollowPerson implements Person{
	@Override
	public String getName() {
		return "yeollow";
	}
}

resource/com.spi.person文件

yeollow=com.spi.YeollowPerson
black=com.spi.BlackPerson
white=com.spi.WhitePerson

mian 方法

package com.spi;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class SPITest {
	
	static Map<String,Class<?>> map = new HashMap<String,Class<?>>();
	
	public static void main(String[] args) throws Exception {
		String fileName = "com.spi.person";
		scanFile(fileName);
		YeollowPerson bean = (YeollowPerson)getBean("yeollow");
		System.out.println(bean.getName());
	}
	
	//根据文件名扫描文件
	static void scanFile(String fileName) throws Exception {
		URL resource = Thread.currentThread()
				.getContextClassLoader()
				.getResource("resource/" + fileName);
		BufferedInputStream bis = (BufferedInputStream) resource.getContent();
		BufferedReader br = new BufferedReader(new InputStreamReader(bis));
		String str = "";
		while((str=br.readLine()) != null) {
			String[] split = str.split("=");
			String name = split[0];
			Class<?> clz = Class.forName(split[1]);
			map.put(name, clz);
		}
	}
	//获取bean
	static Object getBean(String beanName) throws Exception {
		Class<?> clz = map.get(beanName);
		return clz.newInstance();
	}
}

上面就实现了一个自己定制SPI机制,解析的文件可以以任意形式,可以不实现接口 ,文件中直接写类名、种种看自己心情即可
如果比较重要的场景,还是定制一个固定的规范比较好
但是上面是否叫SPI机制,就不知道了,你可以自己命名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值