java插件化開發實例


1.項目分為3個模塊 contract,service和plugin,分別提供 契約,服務和插件

2.在新增、編輯、刪除插件時,不影響service/contract 本身

3.服務實現對字符串的分割,插件實現通過 逗號(comma)和 Tab鍵進行splite

 

4.contract代碼如下:

package org.g2.contract;

public interface Resolver {
    /**
     * 是否支持當前的解析方式
     *
     * @param resolverName 解析方式
     * @return
     */
    String getName();

    /**
     * 解析字符串
     *
     * @param args 原始字符
     * @return 解析后的字符串
     */
    String[] resolve(String args);
}

 

5.service的代碼如下:

package org.g2.service;

import org.g2.contract.Resolver;

import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

public class ResolverFactory {
    public static Map<String, Resolver> load() {
        ServiceLoader<Resolver> resolvers = ServiceLoader.load(Resolver.class);
        Map<String, Resolver> result = new HashMap<>();
        for (Resolver resolver : resolvers) {
            result.put(resolver.getName(), resolver);
        }
        return result;
    }
}

 

package org.g2.service;

import org.g2.contract.Resolver;

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;

/**
 * 入口
 */
public class App {
    public static void main(String[] args) {

        String content = "Hello,World";
        final String type = "comma";
        Map<String, Resolver> resolverMap = ResolverFactory.load();
        String[] resolve = Optional.ofNullable(resolverMap.get(type))
                .orElseThrow(() -> new RuntimeException("不支持的解析類型" + type))
                .resolve(content);
        System.out.println(Arrays.toString(resolve));

        content = "Hello\tWorld";
        final String type2 = "table";
        resolve =Optional.ofNullable(resolverMap.get(type2))
                .orElseThrow(() -> new RuntimeException("不支持的解析類型" + type2))
                .resolve(content);
        System.out.println(Arrays.toString(resolve));
    }
}

 

6.插件模塊(plugin)的代碼如下:

package org.g2.plugin.resolver.comma;

import org.g2.contract.Resolver;

public class CommaResolver implements  Resolver{
    @Override
    public String getName() {
        return "comma";
    }

    @Override
    public String[] resolve(String args) {
        return args.split(",");
    }
}

 

package org.g2.plugin.resolver.table;

import org.g2.contract.Resolver;

public class TableResolver implements Resolver {
    @Override
    public String getName() {
        return "table";
    }

    @Override
    public String[] resolve(String args) {
        return args.split("\t");
    }
}

 

另外,需要在plugin本項目的resources里添加 META-INF/services添加文件 org.g2.contract.Resolver (contract接口的完全路徑名),文件的值為

org.g2.plugin.resolver.comma.CommaResolver
org.g2.plugin.resolver.table.TableResolver

 

7.最后對 service和plugin打包,生成兩個jar包,上傳到linux服務器上后執行如下命令

java -cp plugin-1.0-SNAPSHOT.jar:service-1.0-SNAPSHOT.jar org.g2.service.App

輸出如下

[Hello, World]
[Hello, World]

 

8.后記

在windows 10 的powerShell執行總是不成功,在linux上才成功。

另外如果用 

java -cp plugin-1.0-SNAPSHOT.jar -jar service-1.0-SNAPSHOT.jar

也是不成功的。參考:Simple ServiceLoader - java.util.ServiceConfigurationError ... Provider ... not found - Stack Overflow

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM