【溯源码燕窝重量】【jdk 源码 hashmap】【仿720源码】c webapp源码

时间:2024-12-28 05:45:31 来源:欺天源码论坛 分类:焦点

1.如何评价 React Native
2.spring启动原理(spring工程启动)
3.springboot启动类原理?

c  webapp源码

如何评价 React Native

       React native充分利用了Facebook的现有轮子,是一个很优秀的集成作品,并且我相信这个团队对前端的了解很深刻,否则不可能让Native code「退居二线」。

       å¯¹åº”到前端开发,整个系统结构是这样:

       JSX vs HTML

       CSS-layout vs css

       ECMAScript 6 vs ECMAScript 5

       React native View vs DOM

       æ— éœ€ç¼–译,我在第一次编译了ipa装好以后,就再也没更新过app,只要更新云端的js代码,reload一下,整个界面就全变了。

       å¤šæ•°å¸ƒå±€ä»£ç éƒ½æ˜¯JSX,所有Native组件都是标签化的,这对于前端程序员来说,降低了不少学习成本,也大大减少了代码量。不信你可以看看JSX编译后的代码。

       å¤ç”¨React系统,也减少了一定学习和开发成本,更重要的是利用了React里面的分层和diff机制。js层传给Native层的是一个diff后的json,然后由Native将这个数据映射成真正的布局视图。

       css-layout也是点睛之笔,前端可以继续用熟悉的类css方式来编写布局,通过这个工具转换成constrain布局。

       ç³»

       ç»Ÿåªæœ‰js-objc的单向调用,就是把原生UI组件的方法通过javascritcore或者webview(低版本iOS)映射到js中来,整个调用

       è¿‡ç¨‹æ˜¯å¼‚步的,这样的设计令React native可以让js运行在桌面chrome中,通过websocket连接Native

       code和桌面chrome,极大地方便了调试。对其中的机制Bang的一篇文章写得很详细,我就不拾人牙慧了:React Native通信机制详解 « bang’s blog 。但这样设计也会带来一些问题,后面说。

       ç‚¹æŒ‰æ“ä½œä¹Ÿè¢«æŠ½è±¡æˆäº†ä¸€ç»„组件(TouchableXXX),这种抽象方式是我在之前做类似工作中没有想到的。facebook还列出Native为什么和web「手感」不同的原因:实时的点按反馈和取消能力。React Native 这套相应机制设计得很完善,能像Native code那样控制整个点按操作的所有过程。

       Debug

       ç›¸å½“方便!修改了js以后,通过内建的nodejs

       watcher编译成bundle,在模拟器里面按cmd+r就可以看到效果。而且按cmd+d,可以打开一个chrome窗口,所有的js都移到了

       chrome里面运行,所以什么断点单步打调用栈,都不在话下。

       ä¸Šé¢çš„既是特点也是优点,下面说说缺点,或者应该说:「仍然遗留的问题」,在我看来,这个方案已经超越了Hybird方案。

       ç³»

       ç»Ÿä»ç„¶ï¼ˆä¸å¾—不)依赖原生组件暴露出来的组件和方法。举两个例子,ScrollView这个组件,在Native层是有大量事件

       çš„,scrollViewWillBeginDragging,

       scrollViewWillEndDragging,scrollViewDidEndDragging等等,这些事件在现有的版本都没有暴露,基本上

       åšä¸äº†ç»„件联动效果。另外,这个版本中有大量组件是iOS

       only的:ActivityIndicatorIOS、DatePickerIOS、NavigatorIOS、PickerIOS、

       SliderIOS、SwitchIOS、TabBarIOS、AlertIOS、AppStateIOS、LinkingIOS、

       PushNotificationIOS、StatusBarIOS、VibrationIOS,反过来看,剩余的都是一些抽象程度极强的基本组件。这

       æ ·ï¼Œç”¨æˆ·å¿…须在不同的平台下写两套代码,而且所有能力仍然强烈依赖 React native 开发人员暴露的接口。

       ç”±äºŽæœ€å¤–层是

       React,初次学习成本高,不像往常的Hybird方案,只要多学几个JS

       API就可以开始干活了。当然,React的确让后续开发变得简单了一些,这么一套外来的(基于iOS)、残缺不全的(css-layout)在

       React的包装下,的确显得不那么面目可憎了。

       å¦å¤–,React Native仍然很不完善。文档还不全,我基本上是看着他的示例代码完成的demo,集成到已有app的文档也是今天才出来。按照官方的说法,Android版本要到半年后才发布:Blog | React ,届时整个系统设计可能还会有很大的变化。

       PS,在使用Tabbar的时候,我惊喜的发现他们居然用了iconfont方案,我现在手头的项目中也有同样的实现,不过API怎么设计一直很头疼。结果,我发现他是这么写的:

       <TabBarItemIOS

        name="blueTab"

        icon={ _ix_DEPRECATED('favorites')}

       ....>

       åœ¨ _ix_DEPRECATED 的定义处,有一句注释: // TODO(nicklockwood): How can this 溯源码燕窝重量fit our require system?

       ä»¥ä¸Šã€‚

       ä¸‹é¢æ˜¯ä¸€å‘¨å‰ï¼Œåœ¨React native还没开源的时候,通过反解ipa的一些分析过程,有兴趣的可以看看。

       ------------------------简单粗暴的分割线--------------------

       èƒŒæ™¯å’Œè°ƒç ”手段

       React

        Native还没开源,最近和组里兄弟「反编译」了Facebook Group(这个应用是用React

       Native实现的)的ipa代码,出来几百个JS文件,格式化一下,花了几天时间读了一下源码,对React

       Native的内部核心机制算是有了一个基本了解。

       React Native的核心实现:

       å…ˆç®€å•è¯´å‡ ç‚¹ï¼Œè¯¦ç»†çš„等回头更新。

       1. React Native里面没有webview,这货不是Hybrid app,里面执行JS是用的

       JavascriptCore。

       2. 再说React Native的核心,iOS Native code提供了十来个最基本核心的类(RCTDeviceEventEmitter、

       RCTRenderingPerf等)、或组件(RCTView、RCTTextField、RCTTextView、

       RCTModalFullscreenView等),然后由React Native的JS部分,组成二十来个基本组件(Popover、Listview等),交由上层的业务方来使用(THGroupView)。

       3. 就如他们在宣传时所说,他们实现了一套类似css的子集,用来解决样式问题,相当复杂和强大,靠这个才能将Native的核心组件组成JS层的基本组件再组成业务端的业务组件,应该是采用facebook/css-layout · GitHub的C语言版本实现的(在ppt中我们看到了类似flex-direction: column一类的代码,这个正是css-layout支持的语法)。

       4. 在React Native中,写JS的工程师解决的是「将基本组件拼装成可用的React组件」的问题,写Native Code的工程师解决的是「提供核心组件,提供足够的扩展性、灵活性和性能」的问题。

       React Native的设计考虑:

       ReactJS对React Native有着直接的影响(我没在生产环境中用过React,只看过代码&用过Angular,如果有误请指出)

       ReactJS里面有这样的设计:

       1. ReactJS 的大工厂入口createElement返回的不是某个实体DOM对象,而只是一个数组

       2. 通过源码中 ui/browser/ 目录中的代码,将这个数组转换成DOM

       3. 底层的渲染核心是可以更换的

       å¦å¤–,Facebook自己有JSX,css-layout等开源项目,基于这些,如果要做一个用 JS来开发Native app的东西,很自然就想到了一套最有效率的搞法:

       1. 将 ui/browser 里面的代码替换成一套 Native 的桥接JS(实际上,iOS版是通过

       injectGenericComponentClass方法,将核心组件的方法注入到JS里面 ),就直接复用React的MVVM,自动将数据映射到Native了

       2.

        Native

       code里面实现三组核心API,一组提供核心组件的API(create、update、delete),一组事件方法(ReactJS里面的

       EventEmitter ),一组对css进行解析(css-layout)以及返回Style的ComputedStyle(React

       Native里面叫meatureStyle)。

       è¿™æ ·ï¼Œç”¨ä¸Šäº†ReactJS本身的所有核心功能和设计思路,Native的开发也足够简单。

       é‚£ï¼ŒReact Native是什么?

       å…¶å®žè¿™ä¸œè¥¿ä»ŽNative开发来说,相当于重新发明了一个浏览器渲染引擎并且套一个React的壳,从Web开发角度来说,就是把原来React的后端换成了Native code来实现,就跟Flipboard最近搞的React Canvas 一样: Flipboard · GitHubreact-canvas

       React Native的优势和劣势::

       ä¼˜åŠ¿ç›¸å¯¹Hybird app或者Webapp:

       1. 不用Webview,彻底摆脱了Webview让人不爽的交互和性能问题

       2. 有较强的扩展性,这是因为Native端提供的是基本控件,JS可以自由组合使用

       3. 可以直接使用Native原生的「牛逼」动画(在FB Group这个app里面,面板滑出带一点果冻弹动,面板基于某个点展开这种动画随处可见,这种动画用Native code来做小菜一碟,但是用Web来做就难上加难)。

       ä¼˜åŠ¿ç›¸å¯¹äºŽNative app:

       1. 可以通过更新远端JS,直接更新app,不过这快成为各家大型Native app的标配了…

       åŠ£åŠ¿ï¼š

       1. 扩展性仍然远远不如web,也远远不如直接写Native code(这个不用废话解释了吧)

       2.

       ä»ŽNative到Web,要做很多概念转换,势必造成双方都要妥协。比如web要用一套CSS的阉割版,Native通过css-layout拿到最终样

       å¼å†è½¬æ¢æˆnative原生的表达方式(比如iOS的Constraint\origin\Center等属性),再比如动画。另外,若Android和

       iOS都要做相同的封装,概念转换就更复杂了。

       æ›´æ–°1:添加了React对React Native的影响。

       æ›´æ–°2:基本确定其使用了 css-layout,添加了对React Native的总结

       æ›´æ–°3: React native已经开源了: React Native,只有iOS版。我写了几个demo,简单看了看objc代码并和开源前的我们的一些结论(见后文)交叉验证。简单地从前端工程师和系统整体角度说一下React native的特点和优劣吧。

       æ›´æ–°4: 补充了几条优势和与前端开发的对照

spring启动原理(spring工程启动)

       SpringBoot启动原理分析

       è‡ªåŠ¨é…ç½®æ ¸å¿ƒç±»SpringFactoriesLoader

       ä¸Šé¢åœ¨è¯´@EnableAutoConfiguration的时候有说META-INF下的spring.factories文件,那么这个文件是怎么被spring加载到的呢,其实就是SpringFactoriesLoader类。

       SpringFactoriesLoader是一个供Spring内部使用的通用工厂装载器宏闭,SpringFactoriesLoader里有两个方法,

       åœ¨è¿™ä¸ªSpringBoot应用启动过程中,SpringFactoriesLoader做了以下几件事:

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Initializer

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Listener

       åŠ è½½EnvironmentPostProcessor(允许在Spring应用构建之前定制环境配置)

       æŽ¥ä¸‹æ¥åŠ è½½Properties和YAML的PropertySourceLoader(针对SpringBoot的两种配置文件的加载器)

       å„种异常情况的FailureAnalyzer(异常解释器)

       åŠ è½½SpringBoot内部实现的各种AutoConfiguration

       æ¨¡æ¿å¼•æ“ŽTemplateAvailabilityProvider(如Freemarker、Thymeleaf、Jsp、Velocity等)

       æ€»å¾—来说,SpringFactoriesLoader和@EnableAutoConfiguration配合起来,整体功能就是查找spring.factories文件,加载自动配置类。

       æ•´ä½“启动流程

       åœ¨æˆ‘们执行入口类的main方法之后,运行SpringApplication.run,后面new了一个SpringApplication对象,然后执行它的run方法。

       åˆå§‹åŒ–SpringApplicationç±»

       åˆ›å»ºä¸€ä¸ªSpringApplication对象时,会调用它自己的initialize方法

       æ‰§è¡Œæ ¸å¿ƒrun方法

       åˆå§‹åŒ–initialize方法执行完之后,会调用run方法,开始启动SpringBoot。

       é¦–先遍历执行所有通过SpringFactoriesLoader,在当前classpath下的META-INF/spring.factories中查找所有可用的SpringApplicationRunListeners并实例化。调用它们的starting()方法,液蔽通知这些监听器SpringBoot应用启动。

       åˆ›å»ºå¹¶é…ç½®å½“前SpringBoot应用将要使用的Environment,包括当前有效的PropertySource以及Profile。

       éåŽ†è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的environmentPrepared()的方法,通知这些监听器SpringBoot应用的Environment已经完成初始化。

       æ‰“印SpringBoot应用的banner,SpringApplication的showBanner属性为true时,如果classpath下存在banner.txt文件,则打印其内容,否则打印默认banner。

       æ ¹æ®å¯åŠ¨æ—¶è®¾ç½®çš„applicationContextClass和在initialize方法设置的webEnvironment,创建对应的applicationContext。

       åˆ›å»ºå¼‚常解析器,用在启动中发生异常的时候进行异常处理(包括记录日志、释放资源等)。

       è®¾ç½®SpringBoot的Environment,注册SpringBean名称的序列化器BeanNameGenerator,并设置资源加载器ResourceLoader,通过SpringFactoriesLoader加载ApplicationContextInitializer初始化器,调用initialize方法,对创建的ApplicationContext进一步初始化。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的contextPrepared方法,通知闹绝州这些Listener当前ApplicationContext已经创建完毕。

       æœ€æ ¸å¿ƒçš„一步,将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListener的contextLoaded方法,加载准备完毕的ApplicationContext。

       è°ƒç”¨refreshContext,注册一个关闭Spring容器的钩子ShutdownHook,当程序在停止的时候释放资源(包括:销毁Bean,关闭SpringBean的创建工厂等)

       æ³¨ï¼šé’©å­å¯ä»¥åœ¨ä»¥ä¸‹å‡ ç§åœºæ™¯ä¸­è¢«è°ƒç”¨ï¼š

       1)程序正常退出

       2)使用System.exit()

       3)终端使用Ctrl+C触发的中断

       4)系统关闭

       5)使用Killpid命令杀死进程

       èŽ·å–当前所有ApplicationRunner和CommandLineRunner接口的实现类,执行其run方法

       éåŽ†æ‰€æœ‰çš„SpringApplicationRunListener的finished()方法,完成SpringBoot的启动。

       spring工作原理

       Spring的工作原理是让一个对象的创建不用new就可以自动的生产,在运行时与xmlSpring的配置文件来高岩动态的创建对象和调用对象,而不需要通过代码来关联。

       Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

       spring特点是1.方便解耦,简化开发。2.AOP编程的支持。3.声明式事务的支持。4.方便程序的测试。5.方便集成各种优秀框架。6.降低JavaEEAPI的使用难度。7.Java源码是经典学习范例。

       Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中带消受益。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

       Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初戚行御始化时不等对象请求就主动将依赖传递给它。

spring的原理是什么?

       ä¸€ã€IoC(Inversionofcontrol):控制反转\x0d\1、IoC:\x0d\概念:控制权由对象本身转向容器;由容器根据配置蠢衫文件去创建实例并创建各个实例之间的依赖关系\x0d\核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean\x0d\二、AOP(Aspect-OrientedProgramming):面向方面编程。\x0d\1、代理的两种方式:\x0d\静态代理:\x0d\针对每个具体类分别编写代理类。\x0d\针对一个接口编写一个代理类。\x0d\动态代理:\x0d\针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类。\x0d\2、AOP的主要原理:动态代理。\x0d\Spring工作原理\x0d\Spring已经用过一段时间了,感觉Spring是个很不错的框架。内部最核心的就是IOC了,\x0d\动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xmlSpring的配置文件来动态的创建对象,和调用对象里的方法的。\x0d\Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到谈庆的。\x0d\Spring目的含档握:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置内部通过反射去动态的组装对象)\x0d\要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。\x0d\Spring里用的最经典的一个设计模式就是:模板方法模式。

SpringBoot应用启动原理(二)扩展URLClassLoader实现嵌套jar加载

       åœ¨ä¸Šç¯‡æ–‡ç« ã€ŠSpringBoot应用启动原理(一)将启动脚本嵌入jar》中介绍了SpringBoot如何将启动脚本与RunnableJar整合为ExecutableJar的原理,使得生成的jar/war文件可以直接启动

       æœ¬ç¯‡å°†ä»‹ç»SpringBoot如何扩展URLClassLoader实现嵌套jar的类(资源)加载,以启动我们的应友枣旁用。

       é¦–先岩伏,从一个简单的示例开始

       build.gradle

       WebApp.java

       æ‰§è¡Œgradlebuild构建jar包,里面包含应用程序、第三方依赖以及SpringBoot启动程序,其目录结构如下

       æŸ¥çœ‹MANIFEST.MF的内容(MANIFEST.MF文件的作用请自行GOOGLE)

       å¯ä»¥çœ‹åˆ°ï¼Œjar的启动类为org.springframework.boot.loader.JarLauncher,而并不是我们的com.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程好橡上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*http**file**ftp**jar*等,结合对应的URLConnection可以灵活地获取各种协议下的资源

       å¯¹äºŽjar,每个jar都会对应一个url,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/

       jar中的资源,也会对应一个url,并以'!/'分割,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       å¯¹äºŽåŽŸå§‹çš„JarFileURL,只支持一个'!/',SpringBoot扩展了此协议,使其支持多个'!/',以实现jarinjar的资源,如

       jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       è‡ªå®šä¹‰URL的类格式为[pkgs].[protocol].Handler,在运行Launcher的launch方法时调用了JarFile.registerUrlProtocolHandler()以注册自定义的Handler

       åœ¨å¤„理如下URL时,会循环处理'!/'分隔符,从最上层出发,先构造spring-boot-theory.jar的JarFile,再构造spring-aop-5.0.4.RELEASE.jar的JarFile,最后构造指向SpringProxy.class的

       JarURLConnection,通过JarURLConnection的getInputStream方法获取SpringProxy.class内容

       ä»Žä¸€ä¸ªURL,到读取其中的内容,整个过程为

       URLClassLoader可以通过原始的jar协议,加载jar中从class文件

       LaunchedURLClassLoader通过扩展的jar协议,以实现jarinjar这种情况下的class文件加载

       æž„建war包很简单

       æž„建出的war包,其目录机构为

       MANIFEST.MF内容为

       æ­¤æ—¶ï¼Œå¯åŠ¨ç±»å˜ä¸ºäº†org.springframework.boot.loader.WarLauncher,查看WarLauncher实现,其实与JarLauncher并无太大差别

       å·®åˆ«ä»…在于,JarLauncher在构建LauncherURLClassLoader时,会搜索BOOT-INF/classes目录及BOOT-INF/lib目录下jar,WarLauncher在构建LauncherURLClassLoader时,则会搜索WEB-INFO/classes目录及WEB-INFO/lib和WEB-INFO/lib-provided两个目录下的jar

       å¦‚此依赖,构建出的war便支持两种启动方式

       PropretiesLauncher的实现与JarLauncherWarLauncher的实现极为相似,通过PropretiesLauncher可以实现更为轻量的thinjar,其实现方式可自行查阅源码