zoukankan      html  css  js  c++  java
  • 动态加载jar,实现自定义业务

    在实际业务中,我们经常会遇到需要按不同用户实现不同业务逻辑,如果按照最简单粗暴的做法,当然是使用if else ...来实现。

    不过作为一个社会人,这样怎么能体现出我们的战斗力呢,下面我们来实现一个牛叉的方法。

    具体思路:

    将不同的业务逻辑按用户放到不同的jar包,然后系统通过读取jar包,来实现各自业务;

    以后即使用户的逻辑发生变化,也只要把jar包上传到服务器,就可以动态实现,不影响生产环境了。

    1.接口

    public interface InterfaceAction {
    
        public String getId();
    
        public abstract String action();
    }

    2.新建项目

    action.ext.bj

    pom.xml 依赖于base包

    <dependency>
                <groupId>com.qn</groupId>
                <artifactId>action.base</artifactId>
                <version>0.0.1-SNAPSHOT</version>
    </dependency>

     实现接口

    public class ExtBj implements InterfaceAction {
    
        /** 
         * @see action.base.code.InterfaceAction#getId()
         */
        @Override
        public String getId() {
            return "bj";
        }
    
        /** 
         * @see action.base.code.InterfaceAction#action()
         */
        @Override
        public String action() {
            return "This is bj....";
        }
    
    }

    按照此项目新建个action.ext.nt

    实现完接口后,导出jar包,存放到一个目录下;

    3.完成自定义MyClassLoader

    public class MyClassLoader {
    
        private ClassLoader                  loader;
    
        private Map<String, InterfaceAction> actionMap = new HashMap<>();
    
        /**
         * Getter method for property <tt>actionMap</tt>.
         * 
         * @return property value of actionMap
         */
        public Map<String, InterfaceAction> getActionMap() {
            return actionMap;
        }
    
        /**
         * Setter method for property <tt>actionMap</tt>.
         * 
         * @param actionMap value to be assigned to property actionMap
         */
        public void setActionMap(Map<String, InterfaceAction> actionMap) {
            this.actionMap = actionMap;
        }
    
        public void load(String jarFileName) {
            JarFile jarFile = null;
            try {
                File file = new File(jarFileName);
                URL url = new URL("file:" + jarFileName);
                loader = new URLClassLoader(new URL[] { url });
    
                file.lastModified();
                jarFile = new JarFile(file);
                Enumeration<JarEntry> enumFiles = jarFile.entries();
                JarEntry entry;
                //遍历Jar包中的每一个文件
                while (enumFiles.hasMoreElements()) {
                    entry = enumFiles.nextElement();
                    String classFullName = entry.getName();
                    //仅处理.class文件
                    if (classFullName.indexOf("META-INF") < 0 && classFullName.indexOf(".class") > 0) {
                        String className = classFullName.substring(0, classFullName.length() - 6)
                            .replaceAll("/", ".");
                        //使用当前类加载器加载jar包中的类
                        System.out.println("加载类start:" + className);
                        Class<?> clazz = loader.loadClass(className);
                        System.out.println("加载类end:" + clazz);
                        boolean flag = isInterface(clazz, InterfaceAction.class);
                        if (flag) {
                            InterfaceAction ia = ((Class<InterfaceAction>) clazz).newInstance();
                            actionMap.put(ia.getId(), ia);
                            System.out.println(actionMap);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 是否实现该接口
         * @param c
         * @param szInterface
         * @return
         */
        private boolean isInterface(Class c, Class szInterface) {
            Class[] face = c.getInterfaces();
            for (int i = 0, j = face.length; i < j; i++) {
                if (face[i].equals(szInterface)) {
                    return true;
                }
            }
            return false;
        }
    }

    4.接下来就是test了

     public static void main(String[] args) {
            MyClassLoader ml = new MyClassLoader();
            ml.load("D:\temp\action.ext.bj.jar");
            ml.load("D:\temp\action.ext.nt.jar");
            String s = ml.getActionMap().get("nt").action();
            System.out.println(s);
        }
    加载类start:action.ext.bj.ExtBj
    加载类end:class action.ext.bj.ExtBj
    {bj=action.ext.bj.ExtBj@5cd73256}
    加载类start:action.ext.nt.ExtNt
    加载类end:class action.ext.nt.ExtNt
    {nt=action.ext.nt.ExtNt@6f580c3a, bj=action.ext.bj.ExtBj@5cd73256}
    This is nt.....

    韦爵爷说过:大功告成。。。

  • 相关阅读:
    JS中使用正则表达式封装的一些常用的格式验证的方法-是否外部url、是否小写、邮箱格式、是否字符、是否数组
    Java中操作字符串的工具类-判空、截取、格式化、转换驼峰、转集合和list、是否包含
    Cocos2d-x 2.0 自适应多种分辨率
    应用自定义移动设备外观
    为移动设备应用程序创建外观
    【2020-11-28】人生十三信条
    【2020-11-27】事实证明,逃避是下等策略
    Python 之web动态服务器
    Python 之pygame飞机游戏
    PHP 之转换excel表格中的经纬度
  • 原文地址:https://www.cnblogs.com/malaya/p/9149427.html
Copyright © 2011-2022 走看看