如何在不重新部署整个程序的情况下为界面添加新实现?

时间:2016-05-30 15:09:49

标签: java

我有一个Web应用程序,它运行不同的接口实例(执行),具体取决于从用户检索的字符串:

public interface IExecute{
    public void run();
}

public class XExecute implements IExecute {...}

public class YExecute implements IExecute {...}

public class Handler{

    public static run(String executorName){
        IExecute executor = getImple(executorName);
        executor.run();
    }

    private static IExecute getImple(String executorName){
        return (IExecute) Class.forName(executorName+"Execute").getConstructor().newInstance();
    }
}

此程序正常运行。但我偶尔需要在应用程序运行时添加新的IExecute实现。我不想在每次编写新实现时停止/启动应用程序(用于编译新源代码),因为应用程序中正在运行许多操作。 实际上我想要一个解决方案来限制所有进程只是在应用程序运行时编译新的java文件。任何其他解决方案,即使是复杂的解决方案也可以提

2 个答案:

答案 0 :(得分:1)

您能看看OSGI框架:https://www.osgi.org/developer/architecture/

据说:

  

OSGi技术是一组定义动态的规范   Java组件系统。这些规范实现了开发   模型,其中应用程序(动态地)由许多不同的组成   (可重复使用)组件。

动态软件更新对于关键时间关键应用程序非常有意义,可以减少软件演进阶段的停机时间。如今,在OSGi平台上开发了越来越复杂的应用程序。 Eclipse,WebSphere Liberty,JBoss,Glassfish都在使用OSGI框架。

  

添加了服务动态,因此我们可以安装和卸载   捆绑在一起,而其他捆绑可以适应。

希望,这有帮助。

答案 1 :(得分:0)

使用URLClassLoader和ServiceLoader效果很好:

现在我可以创建一些jar文件,其中有一些IExecute的实现。这样做的说明:https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html

应用程序通过类加载器加载这些jar文件。然后,服务加载器加载所有实现。然后通过迭代实现,它找到一个与指定名称匹配的名称。最后它调用run方法。

    File jarsDirectory = new File(path); 
    File[] files = jarsDirectory.listFiles();
    URL[] urls = new URL[files.length];
    for(int i=0;i<files.length;i++)
        urls[i] = files[i].toURI().toURL();
    URLClassLoader classLoader = new URLClassLoader(urls,ClassLoader.getSystemClassLoader());
    ServiceLoader<IExecute> services = ServiceLoader.load(IExecute.class, classLoader);
    Iterator<IExecute> itrs = services.iterator();
    while(itrs.hasNext()){
        IExecute execute = itrs.next();
        if(execute.getClass().getSimpleName().equals("XExecute"))
            execute.run();
    }