jarslink加载java代码_阿里开源框架jarsLink

开源人方腾飞(蚂蚁金服-技术专家)

JarsLink (原名Titan) 是一个基于JAVA的模块化开发框架,它提供在运行时动态加载模块(一个JAR包)、卸载模块和模块间调用的API。目前在微贷事业群广泛使用。

JarsLink的方便之处在于可动态加载jar、还能卸载jar, 同样是Java语言,Android似乎不能动态卸载jar。

动态加载的核心原理是使用了类隔离,做到类隔离是实例化了一个上下文和classLoader

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 根据本地临时文件Jar,初始化模块自己的ClassLoader,初始化Spring Application Context,同时要设置当前线程上下文的ClassLoader问模块的ClassLoader

*

*@parammoduleConfig

*@paramtempFileJarURLs

*@return

*/

private ClassPathXmlApplicationContext loadModuleApplication(ModuleConfig moduleConfig, ListtempFileJarURLs) {

ClassLoader currentClassLoader=Thread.currentThread().getContextClassLoader();//获取模块的ClassLoader

ClassLoader moduleClassLoader = newModuleClassLoader(moduleConfig.getModuleUrl(), applicationContext.getClassLoader(),

getOverridePackages(moduleConfig));try{//把当前线程的ClassLoader切换成模块的

Thread.currentThread().setContextClassLoader(moduleClassLoader);

ModuleApplicationContext moduleApplicationContext= newModuleApplicationContext(applicationContext);

Properties properties=getProperties(moduleConfig);

moduleApplicationContext.setProperties(properties);

moduleApplicationContext.setClassLoader(moduleClassLoader);

moduleApplicationContext.setConfigLocations(findSpringConfigs(tempFileJarURLs, moduleClassLoader,

getExclusionConfigeNameList(properties)));

moduleApplicationContext.refresh();returnmoduleApplicationContext;

}catch(Throwable e) {

CachedIntrospectionResults.clearClassLoader(moduleClassLoader);throwThrowables.propagate(e);

}finally{//还原当前线程的ClassLoader

Thread.currentThread().setContextClassLoader(currentClassLoader);

}

}

View Code

ClassLoader默认逻辑是双亲委托, 即同一个类只能被加载一次, JarsLink覆盖了这个逻辑从而能多次加载同一个类;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 覆盖双亲委派机制

*

*@seeClassLoader#loadClass(String, boolean)*/@Overrideprotected Class> loadClass(String name, boolean resolve) throwsClassNotFoundException {

Class> result = null;synchronized (ModuleClassLoader.class) {if(isEligibleForOverriding(name)) {if(LOGGER.isInfoEnabled()) {

LOGGER.info("Load class for overriding: {}", name);

}

result=loadClassForOverriding(name);

}if (result != null) {//链接类

if(resolve) {

resolveClass(result);

}returnresult;

}

}//使用默认类加载方式

return super.loadClass(name, resolve);

}

View Code

JarsLink可通过设置可自动扫描Jar的版本,如果发现新版本后可卸载老版本Jar,装载新版本Jar。可通过设置线程池的定时器自动扫描,默认是60秒扫一次。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 模块刷新默认间隔,单位秒*/

private static final int DEFAULT_REFRESH_DELAY = 60;/*** 初始化ScheduledExecutor,启动定时任务,扫描数据库的ModuleConfig,并根据逻辑判断启动和卸载模块

*

*@seeInitializingBean#afterPropertiesSet()*/@Overridepublic void afterPropertiesSet() throwsException {//先刷新一次

refreshModuleConfigs();

scheduledExecutor= new ScheduledThreadPoolExecutor(1,new BasicThreadFactory.Builder().namingPattern("module_refresh-schedule-pool-%d").daemon(true).build());

scheduledExecutor

.scheduleWithFixedDelay(this, initialDelay, refreshDelay, TimeUnit.SECONDS);if(LOGGER.isInfoEnabled()) {

LOGGER.info("AbstractModuleRefreshScheduler start");

}

}

View Code

类加载机制

OSGI(java动态模块化系统的一系列规范,由OSGI联盟制定)入门学习资源类加载机制的关系采用的是网状结构,每个模块通过 Export-Package 来声明我要给别人用哪些类,通过 Import-Package来声明我要用别人的哪些类。而TITAN框架采用的是扁平化管理,每个模块都有一个共同的父类,这个父类加载器就是加载ModuleLoader类的加载器,好处是便于维护,每个模块的类做到充分隔离,缺点是会加载重复的Class,适用于模块较少的场景。

框架类图

e5ab8bd4f5e5e76c5c6f4efbe382c508.png

主要接口

AbstractModuleRefreshScheduler:入口类,负责定期扫描本地和内存中的模块是否发生变更,如果变更,则更新模块。

ModuleLoader:模块加载接口(引擎),负责模块的加载。

ModuleManager:模块管理接口(引擎),负责模块管理,在运行时负责注册、卸载及查找模块,并执行Action

Module:模块,一个模块有多个Action。

Action:模块里的执行者。

使用步骤-maven框架下:

1.引入JarsLink的POM

com.alipay.jarslink

jarslink-api

1.5.0.20180213

引入依赖的包

1.7.7

2.6

3.2.1

org.springframework

spring-aop

${org.springframework.version}

org.springframework

spring-web

${org.springframework.version}

true

commons-logging

commons-logging

1.1.3

org.apache.commons

commons-lang3

3.3.2

commons-lang

commons-lang

${apache.commons.lang.version}

org.slf4j

slf4j-api

${slf4j.version}

commons-collections

commons-collections

${apache.commons.collections.version}

com.google.guava

guava

17.0

junit

junit

4.12

2.Spring配置中加载两个主要

3.继承AbstractModuleRefreshScheduler,并提供模块的配置信息

public class ModuleRefreshSchedulerImpl extendsAbstractModuleRefreshScheduler {

@Overridepublic ListqueryModuleConfigs() {returnImmutableList.of(ModuleManagerTest.buildModuleConfig());

}public staticModuleConfig buildModuleConfig() {

URL demoModule= Thread.currentThread().getContextClassLoader().getResource("META-INF/spring/demo-1.0.0.jar");

ModuleConfig moduleConfig= newModuleConfig();

moduleConfig.setName("demo");

moduleConfig.setEnabled(true);

moduleConfig.setVersion("1.0.0.20170621");

moduleConfig.setProperties(ImmutableMap.of("svnPath", newObject()));

moduleConfig.setModuleUrl(ImmutableList.of(demoModule));returnmoduleConfig;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringModule是一个在Spring框架中扮演重要角色的类。它是用来管理和模块的。另外,SpringModule是基于模块管理器(ModuleManager)和模块服务(ModuleService)提供的接口来实现的。它的核心功能是处理模块的生命周期和依赖关系。从最基础的SpringModule开始,它是Spring框架中的核心组件之一。它与其他模块一起构成了Spring的核心容器(Core Container)。核心容器由spring-core、spring-beans、spring-context、spring-context-support和spring-expression(Spring表达式语言)模块组成。除了核心容器外,还有spring-webmvc模块,它提供了Spring的模型-视图-控制器(MVC)和REST Web服务实现,用于Web应用程序。Spring的MVC框架提供了领域模型代码和Web表单之间的清晰分离,并与Spring框架的其他功能集成。综上所述,SpringModule是Spring框架中负责管理和模块的类,它与其他核心模块一起构成了Spring的核心容器,并为Web应用程序提供了MVC和REST Web服务的实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Jarslink源码解析-----SpringModule](https://blog.csdn.net/bigdogLIU/article/details/112343907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring modules介绍](https://blog.csdn.net/tanga842428/article/details/52875673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值