Zhou Study hard, improve every day.

spi学习

2020-08-11
本文 3887 字,阅读全文约需 12 分钟

1.什么是spi

SPI服务发现思想,根据配置文件获取NamespaceUri对应的处理类

即根据配置文件中的映射关系,来确定处理类

2.代码结构

image-20200811163109737

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;
    }
}

Similar Posts

上一篇 centos软件相关

下一篇 xml解析

Comments