【jvm锁源码分析】【openwrt添加源码】【源码转移码】selector源码深入分析
1.Vue3中deep样式穿透的源码使用细节及源码解析
2.Rç¬è«å¿
å¤åºç¡ââCSS+SelectorGadget
3.为什么 querySelectorAll 返回的不是 Array?
4.Spring Configuration:@Import的用法和源码解析
5.@Import({ AutoConfigurationImportSelector.class})
Vue3中deep样式穿透的使用细节及源码解析
在Vue3的开发中,遇到第三方UI库(如element-plus)样式失效的深入问题时,可以借助:deep()方法实现样式穿透。分析首先理解一下 scoped属性的源码作用,它在组件style标签中设置,深入能确保样式隔离,分析jvm锁源码分析避免组件间的源码样式污染。
例如,深入在element-plus的分析组件中,即使设置了宽度,源码由于 scoped属性导致的深入属性选择器不匹配,导致样式无法生效。分析这时,源码:deep()派上了用场。深入它将属性选择器前置,分析如:.el-inputwrapper::v-deep(.bar)会被转换为[data-v-xxxxxxx] .el-inputwrapper .bar,从而定位到UI库的选择器。
源码解析在core-main/packages/compiler-sfc/src/compileStyle.ts中,当遇到 scoped时,openwrt添加源码会使用postcss插件将CSS转换为抽象语法树,然后在processRule函数中,rewriteSelector()方法会处理:deep,将其转换为穿透选择器。
总结来说,当在Vue3中使用第三方UI库时,若样式设置无响应,可以考虑使用:deep()来解决样式穿透问题,以便于精确地控制和修改UI库的源码转移码样式。
Rç¬è«å¿ å¤åºç¡ââCSS+SelectorGadget
CSSï¼å ¨ç§°å«ä½Cascading Style Sheetsï¼å³å±å æ ·å¼è¡¨ãâå±å âæ¯æå½å¨HTMLä¸å¼ç¨äºæ°ä¸ªæ ·å¼æ件ï¼å¹¶ä¸æ ·å¼åçå²çªæ¶ï¼æµè§å¨è½ä¾æ®å±å 顺åºå¤çãâæ ·å¼âæç½é¡µä¸æå大å°ãé¢è²ãå ç´ é´è·ãæåçæ ¼å¼ãHTMLå®ä¹äºç½é¡µçç»æï¼ä½æ¯åªæHTML页é¢çå¸å±å¹¶ä¸ç¾è§ï¼å¯è½åªæ¯ç®åçèç¹å ç´ çæåï¼ä¸ºäºè®©ç½é¡µçèµ·æ¥æ´å¥½çä¸äºï¼è¿éåå©äºCSSãCSSæ¯ç®åå¯ä¸çç½é¡µé¡µé¢æçæ ·å¼æ åï¼æäºå®ç帮å©ï¼é¡µé¢æä¼åå¾æ´ä¸ºç¾è§ãå¦ä¸å¾çå³ä¾§ï¼å³ä¸ºCSSãå°±å±é¨æ¾å¤§æ¥çï¼ä¸å¾æ示就æ¯ä¸ä¸ªCSSæ ·å¼ã大æ¬å·åé¢æ¯ä¸ä¸ªCSSéæ©å¨ï¼æ¤éæ©å¨çæææ¯é¦å éä¸id为head_wrapperä¸class为s-ps-isliteçèç¹ï¼ç¶ååéä¸å ¶å é¨çclass为s-p-topçèç¹ã大æ¬å·å é¨åçå°±æ¯ä¸æ¡æ¡æ ·å¼è§åï¼ä¾å¦positionæå®äºè¿ä¸ªå ç´ çå¸å±æ¹å¼ä¸ºç»å¯¹å¸å±ï¼bottomæå®å ç´ çä¸è¾¹è·ä¸ºåç´ ï¼widthæå®äºå®½åº¦ä¸º%å 满ç¶å ç´ ï¼heightåæå®äºå ç´ çé«åº¦ãä¹å°±æ¯è¯´ï¼æ们å°ä½ç½®ã宽度ãé«åº¦çæ ·å¼é ç½®ç»ä¸åæè¿æ ·çå½¢å¼ï¼ç¶åç¨å¤§æ¬å·æ¬èµ·æ¥ï¼æ¥çå¨å¼å¤´åå ä¸CSSéæ©å¨ï¼è¿å°±ä»£è¡¨è¿ä¸ªæ ·å¼å¯¹CSSéæ©å¨éä¸çå ç´ çæï¼å ç´ å°±ä¼æ ¹æ®æ¤æ ·å¼æ¥å±ç¤ºäºãå¨ç½é¡µä¸ï¼ä¸è¬ä¼ç»ä¸å®ä¹æ´ä¸ªç½é¡µçæ ·å¼è§åï¼å¹¶åå ¥CSSæ件ä¸ï¼å ¶åç¼ä¸ºcssï¼ãå¨HTMLä¸ï¼åªéè¦ç¨linkæ ç¾å³å¯å¼å ¥å好çCSSæ件ï¼è¿æ ·æ´ä¸ªé¡µé¢å°±ä¼åå¾ç¾è§ãä¼é ã
å¨ç¬è«è¿ç¨ä¸é½éè¦ç¬åç®æ çèç¹ï¼æ们ç¥éç½é¡µç±ä¸ä¸ªä¸ªèç¹ç»æï¼CSSéæ©å¨ä¼æ ¹æ®ä¸åçèç¹è®¾ç½®ä¸åçæ ·å¼è§åï¼é£ä»ä¹æ¯èç¹ï¼åææ ·æ¥å®ä½èç¹å¢ï¼ä¸é¢å´ç»è¿ä¸¤ä¸ªé®é¢è¿è¡ä»ç»ã
å¨HTMLä¸ï¼æææ ç¾å®ä¹çå 容é½æ¯èç¹ï¼å®ä»¬ææäºä¸ä¸ªHTML DOMæ ãæ们å çä¸ä»ä¹æ¯DOMï¼DOMæ¯W3Cï¼ä¸ç»´ç½èçï¼çæ åï¼å ¶è±æå ¨ç§°Document Object Modelï¼å³æ档对象模åãå®å®ä¹äºè®¿é®HTMLåXMLææ¡£çæ åï¼W3Cæ档对象模åï¼DOMï¼æ¯ä¸ç«äºå¹³å°åè¯è¨çæ¥å£ï¼å®å 许ç¨åºåèæ¬å¨æå°è®¿é®åæ´æ°ææ¡£çå 容ãç»æåæ ·å¼ãW3C DOMæ å被å为å¦ä¸3个ä¸åçé¨åï¼
æ ¸å¿DOMï¼é对任ä½ç»æåææ¡£çæ å模åã
XML DOMï¼é对XMLææ¡£çæ å模åã
HTML DOMï¼é对HTMLææ¡£çæ å模åã
æ ¹æ®W3CçHTML DOMæ åï¼HTMLææ¡£ä¸çææå 容é½æ¯èç¹ãæ´ä¸ªææ¡£æ¯ä¸ä¸ªææ¡£èç¹ï¼æ¯ä¸ªHTMLå ç´ æ¯å ç´ èç¹ï¼HTMLå ç´ å çææ¬æ¯ææ¬èç¹ï¼æ¯ä¸ªHTMLå±æ§æ¯å±æ§èç¹ï¼æ³¨éæ¯æ³¨éèç¹ãHTML DOMå°HTMLææ¡£è§ä½æ ç»æï¼è¿ç§ç»æ被称为èç¹æ ï¼å¦ä¸å¾æ示ã
èç¹æ ä¸çèç¹å½¼æ¤æ¥æå±çº§å ³ç³»ãæ们常ç¨ç¶ï¼parentï¼ãåï¼childï¼åå å¼ï¼siblingï¼çæ¯è¯æè¿°è¿äºå ³ç³»ãç¶èç¹æ¥æåèç¹ï¼å级çåèç¹è¢«ç§°ä¸ºå å¼èç¹ãå¨èç¹æ ä¸ï¼é¡¶ç«¯èç¹ç§°ä¸ºæ ¹ï¼rootï¼ãé¤äºæ ¹èç¹ä¹å¤ï¼æ¯ä¸ªèç¹é½æç¶èç¹ï¼åæ¶å¯æ¥æä»»ææ°éçåèç¹æå å¼èç¹ãä¸å¾å±ç¤ºäºèç¹æ 以åèç¹ä¹é´çå ³ç³»ã
å¨CSSä¸ï¼æ们使ç¨CSSéæ©å¨æ¥å®ä½èç¹ãä¾å¦ï¼ä¸å¾ä¸divèç¹çid为containerï¼é£ä¹å°±å¯ä»¥è¡¨ç¤ºä¸º#containerï¼å ¶ä¸#å¼å¤´ä»£è¡¨éæ©idï¼å ¶åç´§è·idçå称ãå¦å¤ï¼å¦ææ们æ³éæ©class为wrapperçèç¹ï¼ä¾¿å¯ä»¥ä½¿ç¨.wrapperï¼è¿é以ç¹ï¼.ï¼å¼å¤´ä»£è¡¨éæ©classï¼å ¶åç´§è·classçå称ãå¦å¤ï¼è¿æä¸ç§éæ©æ¹å¼ï¼é£å°±æ¯æ ¹æ®æ ç¾åçéï¼ä¾å¦æ³éæ©äºçº§æ é¢ï¼ç´æ¥ç¨h2å³å¯ãè¿æ¯æ常ç¨ç3ç§è¡¨ç¤ºï¼åå«æ¯æ ¹æ®idãclassãæ ç¾åçéï¼è¯·ç¢è®°å®ä»¬çåæ³ã
å¦å¤ï¼CSSéæ©å¨è¿æ¯æåµå¥éæ©ï¼å个éæ©å¨ä¹é´å ä¸ç©ºæ ¼åéå¼ä¾¿å¯ä»¥ä»£è¡¨åµå¥å ³ç³»ï¼å¦#container .wrapper på代表å éæ©id为containerçèç¹ï¼ç¶åéä¸å ¶å é¨çclass为wrapperçèç¹ï¼ç¶ååè¿ä¸æ¥éä¸å ¶å é¨çpèç¹ãå¦å¤ï¼å¦æä¸å ç©ºæ ¼ï¼å代表并åå ³ç³»ï¼å¦div#container .wrapper p.text代表å éæ©id为containerçdivèç¹ï¼ç¶åéä¸å ¶å é¨çclass为wrapperçèç¹ï¼åè¿ä¸æ¥éä¸å ¶å é¨çclass为textçpèç¹ãè¿å°±æ¯CSSéæ©å¨ï¼å ¶çéåè½è¿æ¯é常强大çãå¦å¤ï¼CSSéæ©å¨è¿æä¸äºå ¶ä»è¯æ³è§åï¼å ·ä½å¦ä¸è¡¨æ示ã
ä½æ¯ï¼è¿æ ·æ¯æ¬¡é½è¦æµªè´¹é¨åæ¶é´å»å¯»æ¾å®ä½ç¹ï¼è¿æ ·æ¢ä¸å¾æ¹ä¾¿ï¼ä¹ä¸é«æï¼é£ä¹å¦ä½æé«ç¬è«ä¸è¿é¨åå·¥ä½çæçå¢ï¼ä»å¤©æç»å¤§å®¶å享ä¸ä¸ªç¬è«çå©å¨ï¼å®å°±æ¯ï¼SelectorGadget æ件ã
point and click CSS selectorsï¼å¼ºå¤§çè°·ææ件CSSçæå¨ï¼æå©äºæ们快éæ¾å°htmlçèç¹ä¿¡æ¯ï¼å®ä¹æ¯æXpath表达å¼ãSelector Gadgetæ¯ä¸ä¸ªå¼æºçChromeæ©å±ç¨åºï¼å¯ä»¥è½»æ¾å°å¨å¤æçç½ç«ä¸çæåéæ©CSSéæ©å¨ãå®è£ æ©å±ç¨åºåï¼è½¬å°ä»»æ页é¢å¹¶å¯å¨å®ãç½ç«å³ä¸æ¹ä¼æå¼ä¸ä¸ªæ¹æ¡ãåå»æ¨å¸æéæ©å¨å¹é ç页é¢å ç´ ï¼å®å°å为绿è²ï¼ãç¶åSelectorGadgetå°ä¸ºè¯¥å ç´ çæä¸ä¸ªæå°çCSSéæ©å¨ï¼å¹¶çªåºæ¾ç¤ºï¼é»è²ï¼éæ©å¨å¹é çææå 容ãç°å¨åå»çªåºæ¾ç¤ºçå ç´ å°å ¶ä»éæ©å¨ä¸å é¤ï¼çº¢è²ï¼ï¼æåå»æªçªåºæ¾ç¤ºçå ç´ å°å ¶æ·»å å°éæ©å¨ãéè¿è¿ä¸ªéæ©åæç»è¿ç¨ï¼SelectorGadgetå¯ä»¥å¸®å©æ¨æ¾å°æ»¡è¶³æ¨éæ±çå®ç¾CSSéæ©å¨ã
é¦å éè¦å®è£ ä¸ä¸è¿ä¸ªç¥å¨ãå¨è°·ææµè§å¨ä¸çåºç¨ååºéï¼æç´¢å°SelectorGadgetæ件ï¼ç¹å»âæ·»å è³Chromeâå³å¯ãå¦æä¸è½æå¼Chromeåºç¨ååºï¼å¯ä»¥éè¿ç½ä¸çå ¶ä»éå¾è·å该æ件ï¼ä¹ååæå¨æ·»å è³è°·ææµè§å¨å³å¯ãæå¨æ·»å æ¹æ³æ¯ï¼æå¼è°·ææµè§å¨æ©å±ç¨åºï¼å¹¶å¼å¯å¼åè 模å¼ï¼å°è¯¥æ件ææ½å°æµè§å¨éï¼å¦æä¸æåï¼å¯ä»¥éæ©âå 载已解åçæ©å±ç¨åºâï¼å°è¯¥æ件夹å å缩å解åæ·»å è¿å»ã
åæ¶å¨é¡µé¢æ ä¸è½çå°çº¢æ¡å¤çSelectorGadgetæ å¿ã
å±ä»¬ä»¥ / ç½é¡µä¸ºä¾ï¼é¦å ç¹å»ç½é¡µä¸æ¹çSelectorGadgetï¼ç¶åå¨ç½é¡µä¸æ¹å¼¹åºSelectorGadgetæ¡ãæ¥ä¸æ¥ï¼å±ä»¬å°è¯ä¸ä¸å¦ä½ä½¿ç¨ï¼æ¯å¦æ们æ³å®ä½âæå¼¹ä¸å®¶2âçèç¹ï¼ç´æ¥ç¹å»å®ï¼åä¼å¨æ¡å æ¾ç¤ºå ¶èç¹ââ.item-titleï¼å¦ä¸å¾ï¼ã绿è²ï¼åå»å¸æéæ©å¨å¹é ç页é¢å ç´ ãé»è²ï¼çæçè¿ä¸ªCSSéæ©å¨ã.item-titleãè½å¹é çææå 容ï¼ä»ä¸å¾å¯ä»¥åç°è¯¥CSSéæ©å¨å¯ä»¥æååªäºä¿¡æ¯ãå½ä½ æé¼ æ æ¾å°è¿äºé«äº®çå ç´ ä¸æ¶ï¼ä¼æ¾ç¤ºçº¢è²ï¼ä»£è¡¨è¦å°å ¶ä»éæ©å¨ä¸å é¤ï¼èåå»æªçªåºæ¾ç¤ºçå ç´ å°å ¶æ·»å å°éæ©å¨ã
å¨å®é æ建CSS表达å¼è¿ç¨ä¸ï¼éè¦æé ç½é¡µå¼åå·¥å ·éçcopy selectoråè½ä½¿ç¨ï¼é常æ¹ä¾¿ãæ¯å¦ï¼å®ä½æå以ä¸ç½é¡µï¼ /allmovies ï¼çº¢æ¡å çææçµå½±å称信æ¯ã
å ·ä½æä½æµç¨å¦ä¸ï¼å¨æä¸çµå½±å称ä¸å³å»ââæ£æ¥ï¼å®ä½å°çµå½±å称çç½é¡µæºç å¤ï¼ç¶åå³å»âcopyâcopy selectorï¼åæå¼SelectorGadgetï¼å¨æ¡å ç²è´´CSS表达å¼ï¼æEnteré®ï¼åç°å¨ç½é¡µä¸åç¡®å®ä½åºè¯¥çµå½±å称ãä½æ们éè¦å®ä½ææççµå½±å称ï¼å¨å·²æçCSS表达å¼ãï¼body > div:nth-child(5) > div.inner-wrapper > div.inner-2col-main > div > ul > li:nth-child(1) > a > span.item-titleï¼ãä¸è¿è¡ä¿®æ¹ï¼è¿éå¯ä»¥åç°ãli:nth-child(1)ãåªéåäºç¬¬ä¸ä¸ªï¼èæ们æééåææï¼å æ¤å»æåé¢çã(1)ãå³å¯ãå¨å ·ä½å®è·µä¸ï¼å¦ä½ä¿®æ¹è¿ææèµäºå°ä¼ä¼´å¯¹ç½é¡µç»æåCSSè¯æ³çç解ãæç»ï¼è·å以ä¸çº¢æ¡å çµå½±å称çCSSéæ©å¨è¡¨è¾¾å¼ä¸ºï¼ãbody > div:nth-child(5) > div.inner-wrapper > div.inner-2col-main > div > ul > li:nth-child > a > span.item-titleããå¨å®é åºç¨ä¸ï¼ä¸åèç¹æ ç¾ä¹é´ç¨ç©ºæ ¼åéï¼ãbody div:nth-child(5) div.inner-wrapper div.inner-2col-main div ul li:nth-child a span.item-titleãã
ä½å¨SelectorGadget使ç¨ä¸ï¼åç°å ¶æ建çCSS表达å¼å¾å¾å¾å¤æï¼å¤§é¨åæ åµä¸å ¶å®ä¹æ¯å¯ä»¥èªå·±æ建CSS表达å¼çãæ建CSSéæ©è¡¨è¾¾å¼çå ³é®å¨äºæ¸ æ¥æ´ä¸ªç½é¡µç»æï¼æ¾å°æ ç¾ä¹é´çå±äºå ³ç³»ãå±æ§å¼å±äºåªä¸ªæ ç¾çï¼å°±å¯ä»¥æ¯è¾å¿«éçæ建ãèä¸æµè§å¨å¾æºè½ï¼é¼ æ å¨æºç ä¸çä½ç½®ï¼å¯ä»¥å¨ç½é¡µæ¾ç¤ºä¸åç°é´å½±ï¼è¿ä¸ªåè½ç®ç´å¤ªé¦äºã以ä¸çº¢æ¡å ææçµå½±ååçCSS表达å¼ä¹å¯ä»¥è¡¨ç¤ºä¸ºï¼ãdiv.movlist ul li a span.item-titleã
ç¶åç¨SelectorGadgetéªè¯ï¼å¦ä¸å¾ï¼åç°é«äº®éä¸çé¨åå°±æ¯ææ³è¦å®ä½çä¿¡æ¯ï¼è¯´æè¿ä¸ªCSS表达å¼æ£ç¡®ã
以ä¸ç®åä»ç»äºå¦ä½æ建CSS表达å¼ï¼å¨ç¬è«è¿ç¨ä¸å®ä½æåç¹å®èç¹æ°æ®æ¯é常éè¦çä¸æ¥ï¼æäºè¿æ¥ææä¸æ¸¸çç²¾åæ°æ®æåä¸æ¸ æ´ãå¸ææ¬æ¬¡æç¨è½ç»æéè¦çå°ä¼ä¼´ä¸ç¹å°å°å¸®å©ï¼
æ´å¤å 容å¯å ³æ³¨å ¬å ±å·âYJYæè½ä¿®ç¼â~~~
å¾æå顾
Rç¬è«å¨å·¥ä½ä¸çä¸ç¹å¦ç¨
Rç¬è«å¿ å¤åºç¡ââHTMLåCSSåè¯
Rç¬è«å¿ å¤åºç¡ââéæç½é¡µ+å¨æç½é¡µ
Rç¬è«å¿ å¤âârvestå ç使ç¨
为什么 querySelectorAll 返回的不是 Array?
查询所有元素涉及到的规范与数组规范不同,因此查询所有元素返回的不是数组类型。
从规范角度看,查询所有元素属于 DOM 规范,而数组属于 ECMAScript 规范。DOM 规范强调平台中立性,但并未在规范中提及与数组相关的概念。
实际上,查询所有元素返回的c array 源码是 NodeList 类型,这与数组有本质区别。Array 类型来源于 ECMAScript 规范,而 NodeList 则是 DOM 中用于表示一组节点的类。
具体到源码层面,Chromium 的实现中,查询所有元素返回的是 StaticElementList 类型。该类封装了选择器字符串并提供了节点集合,但与 JavaScript 数组的实现不同。
JavaScript 数组由 V8 引擎实现,强平源码其长度属性通过特定的偏移量在 JSArray 对象上获取。与此相反,StaticElementList 的长度属性计算逻辑与 JavaScript 数组完全不同。
综上,查询所有元素返回的 NodeList 不是 Array 类型的原因,主要在于两者所属的规范体系不同,以及在实现细节上的差异。
Spring Configuration:@Import的用法和源码解析
Spring 3.0之后的@Configuration注解和注解配置体系替代了XML配置,本文主要讲解@Import的用法和源码解析。@Import的用法
配置类(带有@Configuration注解)不仅可通过@Bean声明bean,还可通过@Import导入其他类。例如,WebMvcConfig类通过@Import导入其他配置类,同时启用@EnableWebMvc。直接导入
配置类上使用@Import可以导入一个或多个类,甚至可以出现在父类注解中。如WebMvcConfig导入DelegatingWebMvcConfiguration等。ImportBeanDefinitionRegistrar和ImportSelector
@Import除了导入配置类,还可以导入实现了ImportBeanDefinitionRegistrar(如@EnableAspectJAutoProxy)和ImportSelector(如@EnableTransactionManagement)的类。源码解析
ConfigurationClassPostProcessor负责处理@Configuration类,通过ConfigurationClassParser解析配置和导入,由ConfigurationClassBeanDefinitionReader注册BeanDefinition。在解析过程中,处理@Import避免循环导入,通过导入链和ImportStack进行判断。处理直接导入时,通过导入链判断循环。
处理注册器和选择器时,提前触发Aware接口方法,然后在适当时机注册导入的类。
总结来说,@Import提供了多种导入方式的灵活性,Spring的源码设计考虑了循环导入和重复解析的处理,展示了其强大的自定义配置能力。@Import({ AutoConfigurationImportSelector.class})
ï¼2ï¼@Import({ AutoConfigurationImportSelector.class})ï¼å°AutoConfigurationImportSelectorè¿ä¸ªç±»å¯¼å ¥å°spring容å¨ä¸ï¼AutoConfigurationImportSelectorå¯ä»¥å¸®å©springbootåºç¨å°ææ符åæ¡ä»¶ç@Configurationé ç½®é½å è½½å°å½åSpringBootå建并使ç¨çIoC容å¨(ApplicationContext)ä¸
继ç»ç 究AutoConfigurationImportSelectorè¿ä¸ªç±»ï¼éè¿æºç åæè¿ä¸ªç±»ä¸æ¯éè¿selectImportsè¿ä¸ªæ¹æ³åè¯springbooté½éè¦å¯¼å ¥é£äºç»ä»¶ï¼
![image-](./images/image-.png)
æ·±å ¥ç 究loadMetadataæ¹æ³
![image-](./images/image-.png)
æ·±å ¥getCandidateConfigurationsæ¹æ³
个æ¹æ³ä¸æä¸ä¸ªéè¦æ¹æ³loadFactoryNamesï¼è¿ä¸ªæ¹æ³æ¯è®©SpringFactoryLoaderå»å è½½ä¸äºç»ä»¶çååã
![image-](./images/image-.png)
继ç»ç¹å¼loadFactoryæ¹æ³
```java
public static ListloadFactoryNames(Class factoryClass, @Nullable ClassLoaderclassLoader) {
//è·ååºå ¥çé®
String factoryClassName = factoryClass.getName();
return(List)loadSpringFactories(classLoader).getOrDefault(factoryClassName,Collections.emptyList());
}
private static Map>loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap result =(MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
//å¦æç±»å è½½å¨ä¸ä¸ºnullï¼åå 载类路å¾ä¸spring.factoriesæ件ï¼å°å ¶ä¸è®¾ç½®çé 置类çå ¨è·¯å¾ä¿¡æ¯å°è£ 为Enumeration类对象
Enumeration urls =classLoader != null ?classLoader.getResources("META-INF/spring.factories") :ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result =new LinkedMultiValueMap();
//循ç¯Enumeration类对象ï¼æ ¹æ®ç¸åºçèç¹ä¿¡æ¯çæProperties对象ï¼éè¿ä¼ å ¥çé®è·åå¼ï¼å¨å°å¼åå²ä¸ºä¸ä¸ªä¸ªå°çå符串转å为Arrayï¼æ¹æ³resultéåä¸
while(urls.hasMoreElements()) {
URL url =(URL)urls.nextElement();
UrlResource resource = newUrlResource(url);
Properties properties =PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 =properties.entrySet().iterator();
while(var6.hasNext()) {
Entry entry= (Entry)var6.next();
String factoryClassName= ((String)entry.getKey()).trim();
String[] var9 =StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var =var9.length;
for(int var = 0;var < var; ++var) {
String factoryName= var9[var];
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
```
ä¼å»è¯»åä¸ä¸ªsprin g.factoriesçæ件ï¼è¯»åä¸å°ä¼è¡¨è¿ä¸ªé误ï¼æ们继ç»æ ¹æ®ä¼çå°ï¼æç»è·¯å¾çé¿è¿æ ·ï¼èè¿ä¸ªæ¯springæä¾çä¸ä¸ªå·¥å ·ç±»
```java
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION ="META-INF/spring.factories";
}
```
å®å ¶å®æ¯å»å è½½ä¸ä¸ªå¤é¨çæ件ï¼èè¿æ件æ¯å¨
![image-](./images/image-.png)
![image-](./images/image-.png)
@EnableAutoConfigurationå°±æ¯ä»classpathä¸æ寻META-INF/spring.factoriesé ç½®æ件ï¼å¹¶å°å ¶ä¸org.springframework.boot.autoconfigure.EnableutoConfiguration对åºçé 置项éè¿åå°ï¼Java Refletionï¼å®ä¾å为对åºçæ 注äº@ConfigurationçJavaConfigå½¢å¼çé 置类ï¼å¹¶å è½½å°IOC容å¨ä¸
以ååç项ç®ä¸ºä¾ï¼å¨é¡¹ç®ä¸å å ¥äºWebç¯å¢ä¾èµå¯å¨å¨ï¼å¯¹åºçWebMvcAutoConfigurationèªå¨é 置类就ä¼çæï¼æå¼è¯¥èªå¨é 置类ä¼åç°ï¼å¨è¯¥é 置类ä¸éè¿å ¨æ³¨è§£é 置类çæ¹å¼å¯¹Spring MVCè¿è¡æéç¯å¢è¿è¡äºé»è®¤é ç½®ï¼å æ¬é»è®¤åç¼ãé»è®¤åç¼ãè§å¾è§£æå¨ãMVCæ ¡éªå¨çãèè¿äºèªå¨é 置类çæ¬è´¨æ¯ä¼ ç»Spring MVCæ¡æ¶ä¸å¯¹åºçXMLé ç½®æ件ï¼åªä¸è¿å¨Spring Bootä¸ä»¥èªå¨é 置类çå½¢å¼è¿è¡äºé¢å é ç½®ãå æ¤ï¼å¨Spring Boot项ç®ä¸å å ¥ç¸å ³ä¾èµå¯å¨å¨åï¼åºæ¬ä¸ä¸éè¦ä»»ä½é 置就å¯ä»¥è¿è¡ç¨åºï¼å½ç¶ï¼æ们ä¹å¯ä»¥å¯¹è¿äºèªå¨é 置类ä¸é»è®¤çé ç½®è¿è¡æ´æ¹
**æ»ç»
**å æ¤springbootåºå±å®ç°èªå¨é ç½®çæ¥éª¤æ¯ï¼
1. springbootåºç¨å¯å¨ï¼
2. @SpringBootApplicationèµ·ä½ç¨ï¼
3. @EnableAutoConfigurationï¼
4. @AutoConfigurationPackageï¼è¿ä¸ªç»å注解主è¦æ¯@Import(AutoConfigurationPackages.Registrar.class)ï¼å®éè¿å°Registrarç±»å¯¼å ¥å°å®¹å¨ä¸ï¼èRegistrarç±»ä½ç¨æ¯æ«æ主é 置类å级ç®å½ä»¥ååå ï¼å¹¶å°ç¸åºçç»ä»¶å¯¼å ¥å°springbootå建管çç容å¨ä¸ï¼
5.
@Import(AutoConfigurationImportSelector.class)ï¼å®éè¿å°AutoConfigurationImportSelectorç±»å¯¼å ¥å°å®¹å¨ä¸ï¼AutoConfigurationImportSelectorç±»ä½ç¨æ¯éè¿selectImportsæ¹æ³æ§è¡çè¿ç¨ä¸ï¼ä¼ä½¿ç¨å é¨å·¥å ·ç±»SpringFactoriesLoaderï¼æ¥æ¾classpathä¸ææjarå ä¸çMETA-INF/spring.factoriesè¿è¡å è½½ï¼å®ç°å°é 置类信æ¯äº¤ç»SpringFactoryå è½½å¨è¿è¡ä¸ç³»åç容å¨å建è¿ç¨
åå¦äºæå¾æè²çãJavaå·¥ç¨å¸é«èªè®ç»è¥ãï¼çå°åå¦å°çç¹å°±åçäºãå¸ææå¾è½ç»ææ¨å°æ³å»çå ¬å¸ï¼ç®æ ï¼åèï¼ï¼