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

从原理和源码梳理SpringbootFatJar的机制

  一、概述
  SpringBootFatJar的设计,打破了标准jar的结构,在jar包内携带了其所依赖的jar包,通过jar中的main方法创建自己的类加载器,来识别加载运行其不规范的目录下的代码和依赖。二、标准的jar包结构
  打开Java的Jar文件我们经常可以看到文件中包含着一个METAINF目录,这个目录下会有一些文件,其中必有一个MANIFEST。MF,这个文件描述了该Jar文件的很多信息其中MainClass定义Jar文件的入口类,该类必须是一个可执行的类,一旦定义了该属性即可通过javajarxxx。jar来运行该jar文件。
  在生产环境是使用javajarxxx。jar的方式来运行SpringBoot程序。这种情况下,SpringBoot应用真实的启动类并不是我们所定义的带有main方法的类,而是JarLauncher类。查看SpringBoot所打成的FatJar,其MainClass是org。springframework。boot。loader。JarLauncher,这便是微妙之处。SpringBootVersion:2。1。3。RELEASEMainClass:org。springframework。boot。loader。JarLauncherStartClass:com。rock。springbootlearn。SpringbootLearnApplicationSpringBootClasses:BOOTINFclassesSpringBootLib:BOOTINFlibBuildJdk:1。8。0131复制代码
  JAR包中的MANIFEST。MF文件详解以及编写规范三、探索JarLauncher
  org。springframework。boot。loader。JarLauncher这个类是哪里来的呢?答案在springbootloader。jar包中,可找到这个JarLauncher类的源码。在项目中加入maven依赖,以便查看源码和远程调试。dependencygroupIdorg。springframework。bootgroupIdspringbootloaderartifactIddependency复制代码
  认真比较可以看出,这个springbootloader包中的内容与SpringBoot的FatJar包中的一部分内容几乎一样。JarLauncher在jar中的位置如下:
  3。1只能拷贝出来一份儿
  重点重点重点:因jar规范要求MainClass所指定的类必须位于jar包的顶层目录下,即org。springframework。boot。loader。JarLauncher这个org必须位于jar包中的第一级目录,不能放置在其他的目录下。所以所以所以只能将springbootloader这个jar包的内容拷贝出来,而不是整个jar直接放置于执行Jar中。3。2携带程序所依赖的jar而非仅class
  上边JarLauncher的这个org。springframework。xx以及METAINF这两个目录是符合jar包规范的。但是BOOTINF这个目录里边有点像我们开发中的一些用法:依赖jar包在lib目录下但按照jar包规范jar中不能有jar包的情况下程序。class文件在classes目录下但xxx。class文件应该按照org。springframework。xx这样放置在jar中的根目录中
  所以classes和lib你也能意识到,这个设计是独特的。早期jar包内携带依赖是采用如mavenshadeplugin的做法,把依赖的class文件拷贝到目标jar中,但也会造成重名(全限定名)的类会出现覆盖的情况。后来SpringBoot为了避免覆盖的情况,修改了打包机制,放弃了mavenshadeplugin那种拷贝class的方式,调整为依赖原始jar包;这同时意味着改变了Jar标准的运行机制,那么要想让classes和lib中代码能够正常运行,你试想一下如果没有自定义的classLoader来加载这些类文件,可以嘛?四、自定义类加载器的运行机制
  自定义类加载器的常规处理:指定资源指定委托关系指定线程上下文类加载器调用逻辑入口方法4。1指定资源
  构造方法中基于jar包的文件系统信息,构造Archive对象publicExecutableArchiveLauncher(){this。archivecreateArchive();}protectedfinalArchivecreateArchive()throwsException{ProtectionDomainprotectionDomaingetClass()。getProtectionDomain();CodeSourcecodeSourceprotectionDomain。getCodeSource();URIlocation(codeSource!null)?codeSource。getLocation()。toURI():null;Stringpath(location!null)?location。getSchemeSpecificPart():null;if(pathnull){thrownewIllegalStateException(Unabletodeterminecodesourcearchive);}FilerootnewFile(path);if(!root。exists()){thrownewIllegalStateException(Unabletodeterminecodesourcearchivefromroot);}return(root。isDirectory()?newExplodedArchive(root):newJarFileArchive(root));}复制代码
  采集jar包中的classes和lib目录下的归档文件。后边创建ClassLoader的时候作为参数传入OverrideprotectedListgetClassPathArchives()throwsException{ListarchivesnewArrayList(this。archive。getNestedArchives(this::isNestedArchive));postProcessClassPathArchives(archives);returnarchives;}protectedbooleanisNestedArchive(Archive。Entryentry){if(entry。isDirectory()){returnentry。getName()。equals(BOOTINFCLASSES);}returnentry。getName()。startsWith(BOOTINFLIB);}复制代码publicstaticvoidmain(String〔〕args)throwsException{newJarLauncher()。launch(args);}复制代码4。2创建自定义ClassLoaderprotectedvoidlaunch(String〔〕args)throwsException{JarFile。registerUrlProtocolHandler();创建类加载器,并指定归档文件ClassLoaderclassLoadercreateClassLoader(getClassPathArchives());launch(args,getMainClass(),classLoader);}创建类加载器,将归档文件转换为URLprotectedClassLoadercreateClassLoader(Listarchives)throwsException{ListURLurlsnewArrayList(archives。size());for(Archivearchive:archives){urls。add(archive。getUrl());}returncreateClassLoader(urls。toArray(newURL〔0〕));}父加载器是AppClassLoaderprotectedClassLoadercreateClassLoader(URL〔〕urls)throwsException{getClass()。getClassLoader()是系统类加载器,因为默认情况下main方法所在类是由SystemClassLoader加载的,默认情况下是AppClassLoader。returnnewLaunchedURLClassLoader(urls,getClass()。getClassLoader());}复制代码4。3设置线程上下文类加载器,调用程序中的mainclasspublicstaticvoidmain(String〔〕args)throwsException{newJarLauncher()。launch(args);}protectedvoidlaunch(String〔〕args,StringmainClass,ClassLoaderclassLoader)throwsException{设置线程上下文类加载器Thread。currentThread()。setContextClassLoader(classLoader);调用MANIFEST。MF中配置的StartClass:xxx的main方法,还带入了参数createMainMethodRunner(mainClass,args,classLoader)。run();}复制代码

对于瘦身水果,专家五种水果热量比猪肉高,要小心,越吃越胖在减肥的世界里,水果有着不可动摇的地位,因为一提到减肥,大多数人首先想到的就是吃水果。刘女士也不例外。她生完孩子后一直在发胖,所以对自己的身材很不满意。哺乳期过后,刘女士开始了自己分手22年后,巍子和史兰芽的人生状况,一个天上一个地下令人惋惜1973年,黄河边上一个叫杨家寨的村子里,一个长相粗狂,饿得两眼冒金光的大小伙子正和另一个小伙子扑腾在黄土地上打得火热,而原因只是为了一个白面馒头。那时候谁欺负我,我就跟谁干,主要上海下一步防控分三个阶段,将于6月1日至下旬恢复生产生活正常5月16日上午,上海市副市长宗明上海市卫生健康委员会主任吴静蕾上海市医疗保险局局长夏克家中国工程院院士兼交通大学医学院附属瑞金医院院长宁广,介绍上海新冠肺炎疫情最新情况。宗明表示,吴谨言翻红?吴谨言翻红?于正的新剧传家马上就要播出了,虽然继延禧攻略之后,于正的作品没几部能火的,但是他手下的剧业内外都还挺买账。比如马上要播出的传家,因为聚齐了延禧攻略几乎所有演员,所以非常若再买家电,我一定坚持7买7不买,不是瞎说,是真的踩过坑不知道大家家里在置办家电的时候,有没有踩过坑呢?总之我家那些家电,买的时候可真是让我有够烦心,要么就是不好用,要么就是多花了钱,实在无奈。所以,我给大家总结了一下家电7买7不买的原51岁于和伟做核酸被拍,帅过小鲜肉,人到中年,拼的就是身材5月9日,有网友在社交平台分享出偶遇演员于和伟的画面,并激动配文下楼做核酸,偶遇于和伟老师,前几天其实偶遇过一次,但今天是什么神仙运气,竟然排队在我前面,与此同时,该网友还大赞于和很残酷,销量被剃光头的除了Jeep,还有这3家Jeep恐怕做梦都没有想到,作为越野车鼻祖的它,居然有一天在中国市场被剃了销量光头。就像你永远都不会预料到,曾经富可敌国的万亿恒大,居然在一夜之间变成了负债万亿。很残酷,但这就是现2022年江苏医保住院待遇起付标准报销比例是多少?很多缴纳职工医疗保险的人员,都知道生病住院以后,可以享受医保报销待遇,既可以用医保办支付看病就医的费用,还可以用医保卡买药。但是,很多人不知道医疗保险的住院待遇标准是多少。由于各省最美苏麻喇姑的朱娜,嫁给沙宝亮生一女,婚后隐退当家庭主妇编辑小情书在最困难的时候,她能帮你把心里的积怨都摘开,陪你一起哭一起笑,她就是我的真爱!回忆起那些年妻子陪他度过的名不见经传的岁月,沙宝亮满眼温柔。的确,沙宝亮在和妻子朱娜结婚之前残疾人志愿者残缺遮掩不了美丽,用奉献点亮青春时代各有不同,青春一脉相承。一代又一代青年,他们心中点亮理想之灯发出信念之光,让青春在祖国和人民最需要的地方绽放绚丽之花!来自张家口外语学院2018级英语专业的学生冀鲁豫就是其中之中国领先欧美的5项硬核科技,中国崛起之路,越来越顺利中国这些年紧赶慢赶,已经有数十项硬核科技领先欧美了,今天就先来讲讲其中的5项。1超级钢超级钢这个东西,听名字就很牛,事实上上,它还就真厉害,是一次钢铁领域中重大革命,为此,对于其的
岳飞的悲剧岳飞岳飞含冤而死的时候不过39岁,此时的官职已经是武将最高级了,按今天的职级来说就是元帅级别的人了,所统领的军队是南宋的主力,南宋唯一骑兵队伍就在岳飞的统领之下。岳飞主张抗金,主张能走南北二京,不走楚旺回隆?不走神标豆公?过去,冀南豫北流传一句话,能走南北二京,不走楚旺回隆,但是这句话还有另外几个版本,也有说不走泊口回隆,还有说不走神庙豆公,不走施济故城等等,总之,这些俗语都说明了冀南豫北一带治安不明代皇权在不断的重构中,有遇到哪些困境吗?如何解决的?公元1368年建立的明王朝不仅仅在文化上奉行驱逐胡虏,恢复中华的华夏本位主义政策,更是在政制上取法唐宋,奉天法古,力图恢复周制这一几千年来儒家的理想政治制度,从而重构起一个以绝对皇奥古斯都,罗马的第一位皇帝,他带领罗马度过了混乱文思问录编辑思问录公元1914年4月11日,罗马最有影响力的人世界历史上最重要的人物之一去世。据报道,他的遗言是我发现罗马是一座砖城,而留下了一座大理石城。没有什么能更好地描述奥古云南回民起义(40)第一次寻甸会战寻甸,嵩明位于昆明城东北方向,是从东北方向进入昆明的门户,具有极其重要的战略位置。1868年3月,滇西回民起义军进至昆明城郊,已经降清的滇东,滇南回民起义军一部反正响应杜文秀部回军春秋自这一标志性事件起名义上,周王室是中央政权,郑国是其下属的诸侯国,并不平等的双方却互换人质,岂非咄咄怪事?实际上,自周幽王烽火戏诸侯以及周平王东迁雒邑以来,周天子的权威已经崩溃,但周王及各诸侯都没将成都一郊区33年管辖14个县,堪称巴蜀第一,如今备受冷落?每个人,每个地方都有属于自己曾经的荣光,城市当然也是如此。都作为当下中国最著名的城市之一,几乎无人不知无人不晓,但是很多人不知道历史上有很长一段时间,成都西边有一个区反而更加壮大,刘邦为什么要杀死韩信?之所以我的汉高祖刘邦能创下宏伟大业,还得靠那些将领们的牺牲来换的,可是韩信是刘邦最得力的部下,可以韩信最后为什么会被刘邦杀死呢?难道是因为韩信太强了吗?请听我慢道来,嘿嘿害羞害羞耶完颜宗弼给秦桧的那封信里究竟写了什么金国的都天下兵马元帅完颜宗弼,江湖惯称金兀术,给南宋太师宰相秦桧写了一封信。这是代表官方写的一封很私密的信,一场命案的发生就是因为这封信。信很简单。写信人想把它交付到收信人手里,但蓝戟英特尔锐炫A750显卡价格调整为2099元,降价400元IT之家2月2日消息,英特尔昨日宣布,2月1日开始,英特尔锐炫A750公版显卡的全球价格将从289美元调整为249美元(当前约1683元人民币)。英特尔公版型号国行价格已调整为21小棋童和大师携手出场五羊杯开幕式展现薪火传承54321第30届五羊杯全国象棋冠军邀请赛于2月1日晚在广州文化公园开幕。当柳大华吕钦王天一郑惟桐等象棋大师和棋童走出舞台,台下掌声雷动棋迷兴奋不已。象棋大师和棋童一起出场是本次五
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网