JarsLink-两种demo

本文介绍了如何使用蚂蚁金服的开源项目JarsLink进行Java应用的热更新和加载。作者首先提及了寻找Java热插拔方案的背景,然后通过实践JarsLink,分享了基于main函数和自动更新加载的两种方式,并对比了它们的区别。内容包括带包扫描的@Configuration注解方式和XML配置的方式,以及模块包含多个jar包的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次写,直奔主题吧,JarsLink为蚂蚁金服开源项目,项目地址:GitHub地址。以前一直做过erlang,对于代码更新的热插拔支持很好,做了几年java,一直想寻找java的热插拔,最近项目不太忙,一直在找一些开源项目,无意中看到了Jarslink。随即实践了下,一开始从网络上找了很多例子(大多基于Spring的),都没有成功,因为本人一直在做java后台计算,纯main启动那种,也做过几个ssm项目,大体了解SpringMVC,但是不是特别精通,这次实践绕了一些弯路。

以下只是一些基本的测试,maven依赖及基本使用不说了, 网上一大堆,后期再结合项目进行实践。

自动更新加载:

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.alipay.jarslink.api.ModuleConfig;
import com.alipay.jarslink.api.impl.AbstractModuleRefreshScheduler;
import com.google.common.collect.ImmutableList;

public class ModuleRefreshSchedulerImpl extends AbstractModuleRefreshScheduler {
	@Override   
    public List<ModuleConfig> queryModuleConfigs() {
		List<ModuleConfig> tmp = new ArrayList<ModuleConfig>();
        tmp = ImmutableList.of(buildModuleConfig());
        //下面这个,可以配置多个
//        tmp = ImmutableList.of(buildModuleConfig(),buildModuleConfig1());
        return tmp;
    }  
	public static ModuleConfig buildModuleConfig() {
        URL demoModule = Thread.currentThread().getContextClassLoader().getResource("test-2.0.jar");
        ModuleConfig moduleConfig = new ModuleConfig();
        moduleConfig.setName("hello-world");//设置模块名称
        moduleConfig.setEnabled(true);
        moduleConfig.setVersion("1.0.0");//设置版本
        //下面这个注释了,好像也没啥效果,以后再查查测试吧
//        moduleConfig.setProperties(ImmutableMap.of("svnPath", new Object()));
        moduleConfig.setModuleUrl(ImmutableList.of(demoModule));
        return moduleConfig;
    }
}

 启动Main函数:

import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.alipay.jarslink.api.Module;
import com.alipay.jarslink.api.ModuleConfig;
import com.alipay.jarslink.api.ModuleLoader;
import com.alipay.jarslink.api.ModuleManager;
import com.google.common.collect.ImmutableList;

public class TestMain {
    public static void main(String[] args) {
	GenericXmlApplicationContext context = new GenericXmlApplicationContext();
	context.setValidating(false);
	context.load("classpath*:jarlink.xml");
	context.refresh();
		
	ModuleLoader moduleLoader = (ModuleLoader)context.getBean("moduleLoader");
	ModuleManager moduleManager = (ModuleManager)context.getBean("moduleManager");
		
	URL demoModule = Thread.currentThread().getContextClassLoader().getResource("test.jar");
        ModuleConfig moduleConfig = new ModuleConfig();
        moduleConfig.setName("anno-action");
        moduleConfig.setEnabled(true);
        moduleConfig.setVersion("1.0.0");
        moduleConfig.setModuleUrl(ImmutableList.of(demoModule));
        //扫描模块下的Action
        moduleConfig.addScanPackage("com.hanbon.jarlink");
        Module module = moduleLoader.load(moduleConfig);
        moduleManager.register(module);
        
        List l = moduleManager.getModules();
        for(Object o : l) {
            Module m = (Module)o;
            Map mm = m.getActions();
            Iterator it = mm.keySet().iterator();
            while(it.hasNext()) {
        	Object key = it.next();
        	System.out.println(m.getName()+":"+key+":"+mm.get(key));
            }
        }
        
        System.out.println("Test: " + module.doAction("TestOne", "true"));
    }
}

Jarlink.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--模块加载引擎-->
    <bean id="moduleLoader" name="moduleLoader" class="com.alipay.jarslink.api.impl.ModuleLoaderImpl" />
 
    <!--模块管理器-->
    <bean id="moduleManager" name="moduleManager" class="com.alipay.jarslink.api.impl.ModuleManagerImpl" />
	
    <bean id="moduleRefreshScheduler" class="com.hanbon.test.ModuleRefreshSchedulerImpl">
        <property name="moduleManager" ref="moduleManager" />  
	<property name="moduleLoader" ref="moduleLoader" />  
    </bean> 
</beans>

如上面的代码, main函数和自动加载分别是两种加载方式,并且jar包是两种实现方式,main函数为api加载,ModuleRefreshSchedulerImpl为自动加载。

main函数中为带包扫描,ModuleRefreshSchedulerImpl为xml配置。两个实现方式区别如下:

  • 带包扫描的(需要增加@Configuration注解,有无XML没有关系):

import org.springframework.context.annotation.Configuration;

import com.alipay.jarslink.api.Action;

@Configuration
public class TestOne implements Action<String, Boolean>{

	@Override
	public Boolean execute(String arg0) {
		if(arg0.equals("true"))
			return true;
		return false;
	}

	@Override
	public String getActionName() {
		return "TestOne";
	}
}

 

  • XML配置的(需要在打包的Jar包下存在META-INF/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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
         http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd"
       default-autowire="byName">

    <context:annotation-config/>

    <!--创建Action-->
    <bean id="testOne" class="com.hanbon.jarlink.TestOne"/>

</beans>

模块module包含多个jar包,见:jarslink 模块包含多个jar包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值