版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/namelessfighter/article/details/80955892
背景:在实际项目中,某些业务流程会经常变动,或是存在很多版本。这种场景下可以通过“将业务逻辑打包成jar文件,并动态加载”的方式,实时地更新或新增业务逻辑接口。
1、定义业务逻辑公共接口,用于平台调用
2、定义公共资源列表接口,平台将从该接口获取需要加载的动态类
3、业务上各自实现需要的业务逻辑,并打包成jar包
4、平台监控指定文件路径( 以下代码并不包含此功能,可自行实现;另外对于jar文件版本的更新,需要将已经加载的旧版本业务卸载掉,在下面例子中,就是从ballList中移除)
5、加载JAR文件,获取资源列表,动态Load业务逻辑的java类
6、将业务逻辑java类实例化,并动态调用
-------------公共接口定义-------------
---------资源列表
package test.jar;
public interface IResourceList
{
String[] getResourceList();
}
---------实际资源接口
package test.jar;
public interface IBall
{
void play();
}
-------------业务接口实现-------------
---------Football业务
-----业务类
package test.jar;
public class Football implements IBall
{
@Override
public void play()
{
System.out.println("Football");
}
}
-----资源类
package test.jar;
public class ResourceList implements IResourceList
{
@Override
public String[] getResourceList()
{
return new String[]{"test.jar.Football"};
}
}
注:将资源Football和ResourceList打包为Football.jar文件
---------Basketball业务
-----业务类
package test.jar;
public class Basketball implements IBall
{
@Override
public void play()
{
System.out.println("Basketball");
}
}
-----资源类
package test.jar;
public class ResourceList implements IResourceList
{
@Override
public String[] getResourceList()
{
return new String[]{"test.jar.Basketball"};
}
}
注:将资源Basketball和ResourceList打包为Basketball.jar文件
-------------动态JAR调用-------------
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import test.jar.IBall;
import test.jar.IResourceList;
public class LoadJarClassTest
{
public static void main(String[] args) throws Exception
{
List<IBall> ballList = new ArrayList<IBall>();
String[] jarArr = new String[]{"Football.jar", "Basketball.jar"};
for(String jar:jarArr)
{
String jarFileName = System.getProperty("user.dir") + "\\" + jar;
File jarFile = new File(jarFileName);
URL jarURL = jarFile.toURI().toURL();
// 创建类加载器
ClassLoader loader = new URLClassLoader(new URL[] {
jarURL
});
Class<?> clazz = loader.loadClass("test.jar.ResourceList");// 加载指定类,注意一定要带上类的包名
Thread.currentThread().setContextClassLoader(loader);
Object obj = clazz.newInstance();// 初始化一个实例
if (obj instanceof IResourceList)
{
String[] resourceList = ((IResourceList) obj).getResourceList();
for(String resource:resourceList)
{
Class<?> clazzResource = loader.loadClass(resource);// 加载指定类,注意一定要带上类的包名
Object objResource = clazzResource.newInstance();
if (objResource instanceof IBall)
{
ballList.add((IBall) objResource);
}
}
}
}//end for jarArr
for(IBall ball:ballList)
{
ball.play();
}
}
}
实现步骤:
2、定义公共资源列表接口,平台将从该接口获取需要加载的动态类
3、业务上各自实现需要的业务逻辑,并打包成jar包
4、平台监控指定文件路径( 以下代码并不包含此功能,可自行实现;另外对于jar文件版本的更新,需要将已经加载的旧版本业务卸载掉,在下面例子中,就是从ballList中移除)
5、加载JAR文件,获取资源列表,动态Load业务逻辑的java类
6、将业务逻辑java类实例化,并动态调用
-------------公共接口定义-------------
---------资源列表
package test.jar;
public interface IResourceList
{
String[] getResourceList();
}
---------实际资源接口
package test.jar;
public interface IBall
{
void play();
}
-------------业务接口实现-------------
---------Football业务
-----业务类
package test.jar;
public class Football implements IBall
{
@Override
public void play()
{
System.out.println("Football");
}
}
-----资源类
package test.jar;
public class ResourceList implements IResourceList
{
@Override
public String[] getResourceList()
{
return new String[]{"test.jar.Football"};
}
}
注:将资源Football和ResourceList打包为Football.jar文件
---------Basketball业务
-----业务类
package test.jar;
public class Basketball implements IBall
{
@Override
public void play()
{
System.out.println("Basketball");
}
}
-----资源类
package test.jar;
public class ResourceList implements IResourceList
{
@Override
public String[] getResourceList()
{
return new String[]{"test.jar.Basketball"};
}
}
注:将资源Basketball和ResourceList打包为Basketball.jar文件
-------------动态JAR调用-------------
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import test.jar.IBall;
import test.jar.IResourceList;
public class LoadJarClassTest
{
public static void main(String[] args) throws Exception
{
List<IBall> ballList = new ArrayList<IBall>();
String[] jarArr = new String[]{"Football.jar", "Basketball.jar"};
for(String jar:jarArr)
{
String jarFileName = System.getProperty("user.dir") + "\\" + jar;
File jarFile = new File(jarFileName);
URL jarURL = jarFile.toURI().toURL();
// 创建类加载器
ClassLoader loader = new URLClassLoader(new URL[] {
jarURL
});
Class<?> clazz = loader.loadClass("test.jar.ResourceList");// 加载指定类,注意一定要带上类的包名
Thread.currentThread().setContextClassLoader(loader);
Object obj = clazz.newInstance();// 初始化一个实例
if (obj instanceof IResourceList)
{
String[] resourceList = ((IResourceList) obj).getResourceList();
for(String resource:resourceList)
{
Class<?> clazzResource = loader.loadClass(resource);// 加载指定类,注意一定要带上类的包名
Object objResource = clazzResource.newInstance();
if (objResource instanceof IBall)
{
ballList.add((IBall) objResource);
}
}
}
}//end for jarArr
for(IBall ball:ballList)
{
ball.play();
}
}
}