1.什么是spi
SPI服务发现思想,根据配置文件获取NamespaceUri对应的处理类
即根据配置文件中的映射关系,来确定处理类
2.代码结构
UserService(interface)
package com.beiwu.service;
/**
* @author zhoubing
* @date 2020-08-11 15:48
*/
public interface UserService {
String queryUser(String username);
String parse(String info);
}
UserYoungService
package com.beiwu.service;
import com.beiwu.utils.PrintUtils;
/**
* @author zhoubing
* @date 2020-08-11 15:53
*/
public class UserYoungService implements UserService {
@Override
public String queryUser(String username) {
PrintUtils.printInfo("UserYoungService queryUser" + username);
return "young " + username;
}
@Override
public String parse(String info) {
PrintUtils.printInfo("UserYoungService parse" + info);
return "young parse " + info;
}
}
UserOldService
package com.beiwu.service;
import com.beiwu.utils.PrintUtils;
/**
* @author zhoubing
* @date 2020-08-11 15:53
*/
public class UserOldService implements UserService {
@Override
public String queryUser(String username) {
PrintUtils.printInfo("UserOldService queryUser" + username);
return "old " + username;
}
@Override
public String parse(String info) {
PrintUtils.printInfo("UserOldService parse" + info);
return "parse " + info;
}
}
package com.beiwu.service;
import com.beiwu.utils.PrintUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* @author zhoubing
* @date 2020-08-11 16:02
*/
public class DelegateParse {
private static HashMap<String, Object> parsers;
public static UserService getServiceByName(String useName) throws IOException {
loadParsers();
if (parsers == null || parsers.get(useName) == null) {
// 文件未加载成功 或者未找到全限定名
return null;
}
Object res = parsers.get(useName);
if (res instanceof UserService) {
return (UserService) res;
} else {
Class<?> cls = null;
try {
cls = Class.forName(res.toString());
Object obj = BeanUtils.instantiateClass(cls);
if (obj instanceof UserService) {
parsers.put(useName, obj);
return (UserService) obj;
} else {
PrintUtils.printInfo("this class doesn't match required class");
return null;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
private static void loadParsers() throws IOException {
if (parsers == null) {
synchronized (DelegateParse.class) {
if (parsers == null) {
parsers = new HashMap<>();
//这里可以换成常量值
Properties properties = PropertiesLoaderUtils.loadAllProperties("META-INF/userService.properties");
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
parsers.put(entry.getKey().toString(), entry.getValue());
}
}
}
}
}
}
META-INF/userService.properties
userYoungService=com.beiwu.service.UserYoungService
userOldService=com.beiwu.service.UserOldService
TestSpi
package com.beiwu.service;
import com.beiwu.utils.PrintUtils;
import java.io.IOException;
/**
* @author zhoubing
* @date 2020-08-11 16:01
*/
public class TestSpi {
public static void main(String[] args) throws IOException {
// String useService = "userYoungService";
// String useService="userOldService";
String useService="userKidService";
UserService service = DelegateParse.getServiceByName(useService);
if (service == null) {
PrintUtils.printInfo(" get class error ......");
return;
}
String infoRes = service.parse("info ......");
String userRes = service.queryUser("zhangsan");
PrintUtils.printInfo(infoRes);
PrintUtils.printInfo(userRes);
}
}
如何使用
随机选择使用的类,直接指定userService的名字即可
如何新增处理类
当新增类,只用在META-INF/userService.properties中新增名字和全限定名
userYoungService=com.beiwu.service.UserYoungService
userOldService=com.beiwu.service.UserOldService
userKidService=com.beiwu.service.UserKidService
新建类
package com.beiwu.service;
import com.beiwu.utils.PrintUtils;
/**
* @author zhoubing
* @date 2020-08-11 15:53
*/
public class UserKidService implements UserService {
@Override
public String queryUser(String username) {
PrintUtils.printInfo("UserKidService queryUser" + username);
return "kid " + username;
}
@Override
public String parse(String info) {
PrintUtils.printInfo("UserKidService parse" + info);
return "parse " + info;
}
}