第一次写,直奔主题吧,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包