栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 插件化开发尝试

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 插件化开发尝试

这里使用Java SPI的方式来实现插件化,而开发的插件是一般的java Project。至于更丰富的SpringBoot插件,不一定适用。

  1. 在STS新建一个java project,然后,稍微改下.classpath的文件,将文件目录改成通常的形式:


然后新建一个Interface:

public interface TestInterface {
	String sayHello(String name);
}

然后新建一个实现类:

public class HellToInsky implements TestInterface {

	@Override
	public String sayHello(String name) {
		return "Insky say hello to " + name;
	}

}

在srcmainresourcesmeta-INFservices目录下新建一个包含interface包名和类名的文件,例如com.qb.report.TestInterface,然后在内容中添加实现类的完整名称:
com.qb.report.HellToInsky

然后导出为java jar,放在硬盘某个位置:

2. 将interface类拷贝到我们的Springboot工程中,然后添加如下代码:

	@GetMapping("/testJar")
	public void testJar(HttpServletRequest request, HttpServletResponse response) throws IOException {
		log.info("classLoader={}", this.getClass().getClassLoader());
		ClassLoader cl = new URLClassLoader(new URL[] {new URL("file:" + "D:/test.jar")}, this.getClass().getClassLoader()) ;
		ServiceLoader tests = ServiceLoader.load(TestInterface.class, cl);
		Iterator it = tests.iterator();
		if (it.hasNext()) {
			TestInterface test = it.next();
			String ret = test.sayHello(this.getClass().getSimpleName());
			log.info("ret={}", ret);
			response.getWriter().append(ret);
		}

	}

输出结果:

classLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@7382f612
ret=Insky say hello to JasperController

3.环境
STS4.10.0
java 1.8

  1. 网上的差别
public static void defaultClassLoader() throws MalformedURLException, ClassNotFoundException {
		ClassLoader serviceCL = new URLClassLoader(new URL[] { new URL("file:" + "D:/HelloService.jar"),
				new URL("file:" + "D:/Dog.jar"), new URL("file:" + "D:/Sheep.jar") },
				TestServiceLoader.class.getClassLoader().getParent());
 
		
		ServiceLoader helloServices = ServiceLoader
				.load(((Class) (serviceCL.loadClass("com.test.loader.HelloService"))));
 
		Iterator it = helloServices.iterator();
		while (it.hasNext()) {
			HelloService service = it.next();
			service.sayHello();
		}
	}

这里多了个getParent,会提示:

java.util.ServiceConfigurationError: no a subtype

的错误,而statckoverfloat上说,要加上getParent,我这测试是加上才出错。可能是不同版本的原因。

    public static void loadJarFile(File path) throws Exception {
        URL url = path.toURI().toURL();
        // 可以获取到AppClassLoader,可以提到前面,不用每次都获取一次
        URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        // 加载
        Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
        method.setAccessible(true);
        method.invoke(classLoader, url);
    }

这个会提示:

java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader

的错误,主要是版本问题,我这个版本AppClassLoader 不再继承自URLClassLoader。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/353579.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号