21.Spring Bean及Java类的热部署

简介

​ 在URule Pro中支持Spring Bean及Java类的热部署功能,利用该功能,可将需要热部署的Spring Bean及相关Java类文件实时部署到正在运行的服务器中。 ​ 对于采用客户端服务器模式运行的URule Pro应用,只需要在服务端部署好需要的Spring Bean及相关Java类文件,客户端会自动获取这些已部署的Spring Bean及相关Java类文件信息,并对其进行执加载。

​ 有了这个功能,URule Pro中无论是用户自定义的动作库还是内置动作库相关的Spring Bean及Java类,都可以在服务器运行情况下,实时动态部署。

部署方式

​ 登录系统,在进入团队主页面即可看到Jar文件热部署入口链接,如下图:

​ 打开Jar文件热部署的管理页面,点击工具栏上“添加Jar文件”按钮添加一个新的部署项,在弹出的窗口中输入项目名称,点击“确定”后就会出现文件上传按钮,选择一个合适的jar文件上传即可。如下图所示:

​ 完成之后点击页面工具栏上“部署”,即可将所有部署项中上传的Jar文件动态部署到当前项目中;如果当前项目被当成URule Server使用,同时又在项目里配置了客户端地址,那么在Server上部署完成后,系统会提示我们要不要将这些动态的Jar文件推送到URule客户端,如果选择是,那么这些客户端立即接收到这些Jar文件并动态加载。

Spring配置文件及Jar文件要求

​ 从部署方式上了解到,我们只需要将需要热部署的Jar包上传到系统即可,如果其中要加载Spring Bean,那么还需要定义好Spring的xml配置文件放在Jar包中一并上传,下面来举例说明Spring配置文件及Jar文件打包方式。

​ 假如我们需要部署下面这个Java类文件,内容如下:

package test;
/**
 * @author Jacky.gao
 * @since 2019年1月11日
 */
public class BusinessTest {
    public String hello(String name) {
        System.out.println(new OtherBusiness().getENV());
        return "Hello, "+name;
    }
}

​ 从上面的代码中可以看出,这里的hello方法引用了OtherBusiness类中的getENV方法,OtherBusiness类源码如下:

package test;
/**
 * @author Jacky.gao
 * @since 2019年1月11日
 */
public class OtherBusiness {
    public String getENV() {
        return "环境 is OK...";
    }
}

​ 可以看到getENV方法非常简单,只是返回一个字符串而已,对于BusinessTest类,我们希望它成为一个标准的Spring Bean,所以还要添加一个Spring的xml配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">
    <bean id="dybean" class="test.BusinessTest"></bean>
</beans>

​ 在上面这段xml配置中,test.BusinessTest类被配置成为一个标准的Spring Bean,Bean的ID为dybean。到这里Java类的编写及Spring Bean的xml配置工作就完成了,接下来就需要将它们打包Jar并上传到URule中实际热部署。

​ 为了演示Java类引用多个不同Jar包中其它类库的情形,这里我们把BusinessTest类和OtherBusiness类打成两个Jar文件,分别是main.jar和slave.jar,至于Spring Bean的xml配置文件放在两个Jar文件中任何一个中都可以,只是xml的名称必须是urule-spring-context.xml,且这个名为urule-spring-context.xml的Spring配置文件必须放在Jar文件的根下,这里我们把这个urule-spring-context.xml文件打包在main.jar文件当中。

​ 打包好的main.jar文件结构如下图所示:

打包好的slave.jar文件结构如下图所示:

上面的两个Jar文件中,BusinessTest类和OtherBusiness类都位于test这个package下,所以截图中只看到test这个package。 对于URule Pro来说,每个Jar文件中都可以包含一个名为urule-spring-context.xml的Spring的xml配置文件,如果包含每个文件中的Spring配置文件都会被解析并加载; 当然也可以都不包含,这样热部署时引擎只会加载Jar包中的类。

配置

​ 当我们点击“态部署Jar文件的配置页面”上的部署按钮时,系统会尝试取到知识库里所有已上传的Jar文件,然后通过System.getProperty("java.io.tmpdir")取到当前JVM应用的临时目录,同时在其下创建名为urule-jars的目录,最后取当前系统日期作为Jar文件的最终存储目录。

​ 每次点击“部署”按钮时,系统都会尝试删除原来的由系统日期生成的子目录,再根据当前日期重新创建子目录,再把所有的Jar文件放在这个目录下。

​ 在临时目录中生成好所有的已上传的Jar文件后,接下来系统会尝试加载这个目录下的所有Jar文件,如果这些Jar文件根下包含名为 urule-spring-context.xml的Spring配置文件,系统也会将这个文件加载到Spring上下文中。

​ 实际使用中,如果不想让引擎通过System.getProperty("java.io.tmpdir")这种方式,取到的临时目录来作为动态Jar文件的存储父目录,那么可以在Spring的Properties文件中添加一个名为urule.dynamicJarsPath的属性来手工指定一个用于存储动态Jar文件的 父目录,需要注意的是通过urule.dynamicJarsPath属性指定的目录一定要存在,否则启动时会产生错误。

​ 对于采用客户端服务器模式运行的应用来说,如果客户端是一个Java Web应用,那么只需要按照客户端服务器模式中介绍的在客户端中配置好接收服务端推送过来的知识库的Servlet即可,这样服务端动态Jar部署时会提示是否推送到客户端,如果选是,那么这些动态Jar文件会直接推送到目标客户端,客户端收到后也会按照上述方式加载这些Jar文件及其中可能存在的名为urule-spring-context.xml的Spring配置文件。

​ 和知识包的客户端一样,客户端也可以主动检查服务端是否存在动态Jar文件,检查方式也是在客户端上配置“urule.resporityServerUrl”属性值,客户端中配置好“urule.resporityServerUrl”属性值后,客户端应用除了会利用这个URL到服务端下载规则包,还会在启动时利用这个URL检查服务端是否存在动态加载的Jar文件,如果有则下载到客户端并加载;这时服务端的“urule/dynamic/checkLatestJarsDir”和“urule/dynamic/loadDynamicJars”这两个URL要保证匿名可访问,否则客户端启动时会产生错误。

​ 如果客户端是一个标准的Java应用,而非一个Java Web应用,对于这种类型的应用来说,为了可以取到服务端生成的动态Jar文件,我们可以在客户端Spring的Properties文件中添加一个名为urule.dynamicJarsRemoteLoadInterval的属性 来决定客户端每隔多久利用客户端上配置的urule.resporityServerUrl属性值到服务端检查有没有新的动态Jar产生,如果有则从服务端取回并加载。

urule.dynamicJarsRemoteLoadInterval的属性值单位为分钟,如果我们设置其值为5,那就表示每隔5分钟到服务端检查是否生成新的动态Jar文件,如果不设置则表示客户端不会定期检查服务端是否有新的动态Jar包产生。

如果是springboot项目,需要在spring的配置文件中添加属性配置

spring.main.allow-bean-definition-overriding=true

results matching ""

    No results matching ""