专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

Java类隔离应用多Jar包支持

  案例需求
  现在有一个统一管理平台,用于统一对接三方平台,屏蔽相同业务三方平台的差异性,减少内部平台对接的成本。正常情况下三方平台提供的SDK是通用的(和内部平台无关),但是有一些比较特殊的三方(假如是三方平台A),他提供的SDK是给内部平台定制的。
  这时就需要根据访问统一管理平台的内部平台类型,动态的选择使用哪个三方平台A的Jar包,比如内部平台A访问三方平台A,就需要调用为A定制的Jar包。
  这个需求需要解决如下两个问题:如何在同一套环境中同时存在多个同平台不同版本的Jar包(这些Jar包中的类大部分相同,只有预设的配置参数不同)?如何根据内部平台类型,选择需要调用的Jar包?类加载
  我们知道如果想要使用一个类,那么这个类必须通过类加载器将其加载到内存中,在未自定义类加载器之前,JVM是通过ApplicationClassLoader、ExtensionClassLoader、BootstrapClassLoader这三个类加载器基于双亲委派机制完成类的加载。这三个类加载器具有各自加载类的范围如下图所示:
  类隔离机制
  要想解决上面的第一个问题(多个同平台不同版本Jar包同时存在),就必须先了解一下类隔离机制。
  类隔离机制原理其实很简单,就是让每个三方平台A定制的Jar使用单独的类加载器来加载,这样每个Jar包之间相互隔离不会相互影响。这是因为即使同一个类使用不同的类加载器加载,对于JVM也是两个不同的类(虽然类的结构相同),在JVM中类的唯一标识是:类加载器类名。
  要保证不同Jar包内的类隔离,还需要做到一点,就是Jar包中的某个类使用某个类加载器加载,那么其引用的类均使用该类加载器加载,这就是类加载传导规则。
  代码实现
  使用IDEA创建三个Maven项目:thirdpartyAforA:三方平台A为内部平台A定制的JarthirdpartyAforB:三方平台A为内部平台B定制的Jarunifiedmanagementplatform:统一管理平台,用于通过访问的内部平台类型,动态选择调用三方平台A的Jar
  项目:thirdpartyAforA
  pom。xmllt;?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。thirdparty。AgroupIdthirdpartyAforAartifactIdversion1。0SNAPSHOTversiondescription三方平台A为内部平台A定制Jar包descriptionpropertiesmaven。compiler。source17maven。compiler。sourcemaven。compiler。target17maven。compiler。targetpropertiesdependenciesdependencygroupIdcn。hutoolgroupIdhutoolallartifactIdversion5。8。5versiondependencydependenciesproject
  定义两个类:TPAAccessService:用于提供给调用方的统一调用入口类SendRequestProvider:Jar内部使用的类,用于提供向三方平台A发送请求的类,另外一个作用是验证类加载传导规则
  TPAAccessService。javaTPA(ThirdPartyA:三方平台A简称)该类为调用方提供统一的方法调用入口,调用三方A只需要使用该类即可since20231149:45publicclassTPAAccessService{publicstaticvoidsend(){SendRequestProvider。send();}}
  SendRequestProvider。javaimportcn。hutool。core。lang。Console;该类提供向三方平台A发送请求的方法since20231149:48classSendRequestProvider{三方平台A为内部平台A预设的密钥,用于加解密privatestaticfinalStringSECRETKEYAAAAAAAAAAA;发送请求到三方平台Apublicstaticvoidsend(){Console。log(〔ATPA〕密钥:{}ClassLoader:{},SECRETKEY,SendRequestProvider。class。getClassLoader());}}
  项目:thirdpartyAforB
  与thirdpartyAforA基本相同,除了SendRequestProvider。java中的密钥不同,如下所示:classSendRequestProvider{三方平台A为内部平台B预设的密钥,用于加解密privatestaticfinalStringSECRETKEYBBBBBBBBBBB;发送请求到三方平台Apublicstaticvoidsend(){Console。log(〔BTPA〕密钥:{}ClassLoader:{},SECRETKEY,SendRequestProvider。class。getClassLoader());}}
  项目:
  unifiedmanagementplatform
  pom。xmllt;?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。umpgroupIdunifiedmanagementplatformartifactIdversion1。0SNAPSHOTversiondescription统一管理平台descriptionpropertiesmaven。compiler。source17maven。compiler。sourcemaven。compiler。target17maven。compiler。targetpropertiesdependenciesdependencygroupIdorg。projectlombokgroupIdlombokartifactIdversion1。18。24versiondependencydependencygroupIdcn。hutoolgroupIdhutoolallartifactIdversion5。8。5versiondependencydependenciesproject
  定义两个类:TPAClassLoader:自定义类加载器,用于加载为内部平台定制的相应Jar中类的类Main:测试内部平台调用效果
  TPAClassLoader。javaimportcn。hutool。core。lang。Console;importlombok。SneakyThrows;importjava。io。File;importjava。io。FileNotFoundException;importjava。net。URL;importjava。net。URLClassLoader;importjava。util。concurrent。ConcurrentHashMap;importjava。util。concurrent。ConcurrentMap;为加载三方平台A提供的Jar自定义的类加载器since202311410:02publicclassTPAClassLoaderextendsURLClassLoader{用于缓存相应平台的类加载器,防止重复创建和加载类,造成内存泄漏privatestaticfinalConcurrentMapString,TPAClassLoaderCLASSLOADERCACHEnewConcurrentHashMap();privateTPAClassLoader(URL〔〕urls,ClassLoaderparent){super(urls,parent);}用于获取相应三方平台Jar包中的类,如果已经加载直接返回,未加载通过TAPClassLoader加载类,完成后返回paraminternalPlatformCode内部平台编码,例如:内部平台A的编码就是AparamtapJarPath为相应内部平台定制的三方平台Jar路径paramclassName待获取类的全限定类名return类的Class对象SneakyThrowspublicstaticClasslt;?getClass(StringinternalPlatformCode,StringtapJarPath,StringclassName){TPAClassLoaderclassLoadergetInstance(internalPlatformCode,tapJarPath);Console。log(获取内部平台{}的类:{},internalPlatformCode,className);returnclassLoader。loadClass(className);}用于获取对应内部平台的类加载器,类加载器相对于内部平台是单例的,保证单例使用单例设计模式DCL的方式paraminternalPlatformCode内部平台编码,例如:内部平台A的编码就是AparamtapJarPath为相应内部平台定制的三方平台Jar路径return内部平台对应的类加载器privatestaticTPAClassLoadergetInstance(StringinternalPlatformCode,StringtapJarPath)throwsException{finalStringkeybuildKey(internalPlatformCode,tapJarPath);TPAClassLoaderclassLoaderCLASSLOADERCACHE。get(key);if(classLoader!null){returnclassLoader;}synchronized(TPAClassLoader。class){classLoaderCLASSLOADERCACHE。get(key);if(classLoader!null){returnclassLoader;}FilejarFilenewFile(tapJarPath);if(!jarFile。exists()){thrownewFileNotFoundException(未找到三方平台AJar包文件:tapJarPath);}classLoadernewTPAClassLoader(newURL〔〕{jarFile。toURI()。toURL()},getSystemClassLoader());Console。log(为内部平台{}创建类加载器:{},internalPlatformCode,classLoader);CLASSLOADERCACHE。put(key,classLoader);returnclassLoader;}}用于生成缓存对应内部平台类加载器的KeyparaminternalPlatformCode内部平台编码,例如:内部平台A的编码就是AparamtapJarPath为相应内部平台定制的三方平台Jar路径return缓存KeyprivatestaticStringbuildKey(StringinternalPlatformCode,StringtapJarPath){returninternalPlatformCode。concat(::)。concat(tapJarPath);}}
  Main。javaimportcn。hutool。core。lang。Console;importcn。hutool。core。util。RandomUtil;importcn。hutool。core。util。ReflectUtil;importlombok。SneakyThrows;importjava。util。HashMap;importjava。util。Map;MainauthorZhaoHaichunsince202311410:34publicclassMain{该Map只是测试使用,用于临时保持三方平台A提供的Jar包路径,实际开发会通过文件上传到服务器,然后获取上传路径,通过路径加载privatestaticfinalMapString,StringTPAJARPATHMAPnewHashMap();privatestaticfinalStringTAPACCESSSERVICENAMEcom。thirdparty。TPAAccessService;static{TPAJARPATHMAP。put(A,C:UserszhaohDesktopTemptapjarthirdpartyAforA1。0SNAPSHOT。jar);TPAJARPATHMAP。put(B,C:UserszhaohDesktopTemptapjarthirdpartyAforB1。0SNAPSHOT。jar);}SneakyThrowspublicstaticvoidmain(String〔〕args){for(inti0;i5;i){用于随机生成待访问的内部平台StringinternalPlatformCodeString。valueOf((char)RandomUtil。randomInt(A,B1));通过访问的内部平台查询三方平台A为其提供的Jar路径StringjarPathTPAJARPATHMAP。get(internalPlatformCode);通过上述信息,使用相应的类加载器加载或直接获取类com。thirdparty。TPAAccessServiceClasslt;?clazzTPAClassLoader。getClass(internalPlatformCode,jarPath,TAPACCESSSERVICENAME);调用其相应的方法ReflectUtil。invokeStatic(clazz。getMethod(send));Console。log();}}}测试步骤
  编写完成上述代码后,按照下面步骤执行:使用Mavenpackage打包项目:thirdpartyAforA、thirdpartyAforB将打包完成的Jar拷贝到测试目录,上面实例代码为:C:UserszhaohDesktopTemptapjar目录下修改Main类静态代码块中的路径与Jar包路径一致执行Main类中的main方法
  输出结果如下:(每次输出可能不同)为内部平台A创建类加载器:com。ump。TPAClassLoader568db2f2获取内部平台A的类:com。thirdparty。TPAAccessService〔ATPA〕密钥:AAAAAAAAAAAClassLoader:com。ump。TPAClassLoader568db2f2获取内部平台A的类:com。thirdparty。TPAAccessService〔ATPA〕密钥:AAAAAAAAAAAClassLoader:com。ump。TPAClassLoader568db2f2为内部平台B创建类加载器:com。ump。TPAClassLoader179d3b25获取内部平台B的类:com。thirdparty。TPAAccessService〔BTPA〕密钥:BBBBBBBBBBBClassLoader:com。ump。TPAClassLoader179d3b25获取内部平台B的类:com。thirdparty。TPAAccessService〔BTPA〕密钥:BBBBBBBBBBBClassLoader:com。ump。TPAClassLoader179d3b25获取内部平台A的类:com。thirdparty。TPAAccessService〔ATPA〕密钥:AAAAAAAAAAAClassLoader:com。ump。TPAClassLoader568db2f2
  通过上面的输出结果可以看出:内部平台A和B分别只创建了一次类加载器创建完成类加载器后,后续均通过缓存中获取相应的类加载器在Jar包中TPAAccessService调用了SendRequestProvider,而SendRequestProvider输出的日志中类加载器同加载TPAAccessService的类加载器相同,说明类加载传导规则内部平台A调用,输出的密钥是AAAAAAAAAAA,B调用输出的密钥是BBBBBBBBBBB,说明为内部平台提供的Jar均加载到内存,而且通过类加载器实现了类的隔离

排队上市!科创板成了氢企救命稻草?氢能企业近期迎来一波IPO热潮。日前,上海捷氢科技股份有限公司(以下简称捷氢科技)江苏国富氢能技术装备股份有限公司(以下简称国富氢能)上海治臻新能源股份有限公司(以下简称治臻股份)乌克兰终究是美俄博弈的弃子,俄乌战争最大的受益者是美国司机普哥,咱们都打了快四个月了还没分出胜负,能不能见面聊聊,都休息下冬天接着打?大帝演员,你是不是看着你的好友金毛狮王约翰逊被迫辞职了安倍晋三也被暗杀了,害怕了?司机普哥,我现在手发挥华侨华人作用助力粤港澳大湾区建设来源深圳特区报原标题发挥华侨华人作用助力粤港澳大湾区建设粤港澳大湾区建设是习近平总书记亲自谋划亲自部署亲自推动的重大国家战略。粤港澳大湾区发展规划纲要提出,要积极引导华侨华人参与大经常染发会致癌,到底是真的还是假的?研究结果公布了现在社会是一个非常看脸的时代,每个人都非常在乎自己的外在形象,毕竟现在人们对颜值好,身材优越的人会更包容。为了让自己变得更完美,很多人选择用医美的方式让自己更优秀,而为了提高自己的溥仪一生中最霸气的一次,接受审判时与日本天皇对骂你不要脸中国末代皇帝溥仪的一生可以说是中国自古以来所以皇帝中最戏剧性,最坎坷,最荒诞的。溥仪三岁登基,做了慈禧太后的傀儡皇帝,后来又被迫退位,直到冯玉祥发动北京政变,把他作为满清遗老赶出了亚洲杯诞生53分惨案!14亿人口大国被羞辱,中国进4强拦路虎出炉北京时间7月13日,男篮亚洲杯诞生惨案!首次参加亚洲杯的新西兰男篮,10047狂胜印度男篮,取得开门红。这场比赛第二节,新西兰男篮单节打出349的超级攻势,一举奠定胜局。下半场,新欧元区近7年来首次扩张克罗地亚明年1月正式改用欧元当地时间7月12日,克罗地亚财政部长兹德拉夫科马里奇欧洲央行行长拉加德以及欧盟经济委员会委员保罗真蒂洛尼在比利时布鲁塞尔签署协议,克罗地亚将成为欧元区第20个成员国。根据协议,克罗老师让学生拍作业照片,家长却借此机会炫富,老师将其移出群聊文萌妈教育日记整顿家长群,势在必行。现在科技那么发达,教育的方式也开始多种多样,除了面对面的传统教育模式之外,还有线上教学等方式,在学生们无法返回学校里面上课的时候,给予了很多的帮抛开历史和政治不谈,那你还想谈什么2022年7月8日,也就是七七事变85周年的后一天,日本前首相安倍晋三在奈良街头发表演说时遇刺身亡。消息一出,立刻占据国内热搜第一,成为这几天街头巷尾最常谈的话题之一。这几天,网络法媒英国8名保守党要员获参加党魁竞选资格唐宁街竞选正式开始。据法新社伦敦7月12日报道,8名保守党候选人在当地时间12日获得必要数量的支持后,试图接过鲍里斯约翰逊的首相之位。报道称,不出所料,负责确定选举规则的英国议会下历史惊人的相似,如今的美国像极了灭亡前的明朝,有3点可以印证中华民族有着五千年悠久的历史,在这几千年的时间里,王朝不断更替,各种英雄人物不断涌现,社会形态也不断进化,形成了根基深厚的文明社会。之所以中国能够成为唯一延续至今的古文明,就是因为
黄帝内经记载没有战争的年代古人能活到一百岁,是真的吗?最近看到了不少有关这样的言论,并且说有史料记载,一看,是我们最早的医学著作黄帝内经,说来还挺具有真实性,那么简单考证一下。黄帝内经原文如下岐伯对曰上古之人,其知道者,法于阴阳,和于用心做好每一餐湖南恒康餐饮管理有限公司守合同重信用纪实王亮肖晴岚民以食为天。想经营好一家餐饮企业,要付出的心血格外多,也必须有着坚定的诚信经营理念。有这样一家餐饮企业,专业从事学校企事业单位医院以及工业园区的食堂托管经营与食材配送,成湖南省餐饮行业协会新春团拜湘菜泰斗行业大咖齐聚友友视频加载中红网时刻新闻1月13日讯(记者邓晓娟)1月11日,湖南省餐饮行业协会2023新春团拜会,湖南省餐饮行业协会会长刘国初携湘菜泰斗餐饮前辈行业大咖齐聚友友饭店。大家在开心热闹信银理财积极推动慈善理财业务在浙江上海等地落地开花中证网讯(记者黄一灵)近日,信银理财首次披露慈善理财业务发展规划。据介绍,目前,信银理财携手浙江省慈善联合总会推出的专项慈善理财产品信银理财金睛象项目优选(同富)系列封闭式理财产品浙江省临海市荣膺中国美食地标之都城市品牌来源中国食品报2023年1月12日,浙江省临海市政府新闻办公室在临海远洲国际大酒店举行中国美食地标之都授牌仪式暨新闻发布会。经全国生态食材与生态餐饮评定中心评定,临海市高分通过中国2022年度盘点系列日系群雄纵然几大品牌联盟在今年推出了众多亮眼的新品,但也不要忽视日系群雄们今年的表现。这也是我们2022年度的最后一篇新品盘点文章,接下来我们将会为大家从这些新品之中提炼出十大关键词,给大嘉庆继位时为何要杀和珅?为什么说和坤是二皇帝和坤能够成为乾隆后期的二皇帝,就已经说明了他并非庸庸碌碌之辈。和坤,尽管是官宦子弟,但他幼年父母就已去世,家道衰落尽管是满洲旗人,但在满是皇亲国戚的北京城,却毫不显眼尽管聪明好学,净土宗发源地庐山脚下东林寺风吹一点云,散漫为春雨。洒予松柏林,青葱枝可取。持此岁寒操,手中空楚楚。幽谷无人来,日暮意谁与?宋契嵩古意地理位置坐落在江西省九江市庐山西麓的东林寺,北距九江市16千米,东距庐山牯终于等到!湛江又添一座梦幻童话乐园湛江旅游官方微信公众号关注港城新年新气象,遛娃又添好去处!小象乐园入驻湛江儿童公园2023年1月8日上午正式开园迎客据悉,位于霞山解放东路的湛江儿童公园已经旧貌换新颜随着小象乐园入2个高品质的特色乡村民宿设计点击上方关注本号,更多行业内容推送2个高品质的特色乡村民宿设计1hr王家疃村柿园民宿项目位于中国山东省威海市王家疃村,是一个有百年历史的小村庄。一方面村庄原始格局完好,传统风貌明显湛江制造业骨骼愈加强健来源湛江日报湛江新闻网宝钢湛江钢铁基地高炉。记者郎树臣摄岁末年初,湛江的制造业频传喜讯。宝钢热镀锌吉帕钢(XGPa)DP1310GADP1470GI在湛江钢铁成功下线,标志着宝钢在
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网