重点技术-20180707-JAVA插件式开发-动态JAR包加载

版权声明:本文为博主原创文章,未经博主允许不得转载。 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();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/namelessfighter/article/details/80955892