电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

SpringBoot自動(dòng)裝配原理詳解

瀏覽:99日期:2023-03-21 15:10:12

首先對(duì)于一個(gè)SpringBoot工程來(lái)說(shuō),最明顯的標(biāo)志的就是 @SpringBootApplication它標(biāo)記了這是一個(gè)SpringBoot工程,所以今天的 SpringBoot自動(dòng)裝配原理也就是從它開(kāi)始說(shuō)起。

自動(dòng)裝配流程

首先我們來(lái)看下@SpringBootApplication 這個(gè)注解的背后又有什么玄機(jī)呢,我們按下 ctrl + 鼠標(biāo)左鍵,輕輕的點(diǎn)一下,此時(shí)見(jiàn)證奇跡的時(shí)刻..我們看到如下優(yōu)雅的代碼:

SpringBoot自動(dòng)裝配原理詳解

這其中有兩個(gè)比較容易引起我們注意的地方,一個(gè)是@SpringBootConfiguration注解,另一個(gè)是@EnableAutoConfiguration注解;之所以說(shuō)這個(gè)兩個(gè)注解比較吸引我們的眼球, 不是因?yàn)樗鼈冮L(zhǎng)大的好看,而是因?yàn)槠渌淖⒔馓y看了(主要是因?yàn)槠渌淖⒔馕覀兌际潜容^熟悉,即使不知道他們是干什么的,可以肯定更自動(dòng)裝配是沒(méi)有關(guān)系的)。 然后我們又伸出了邪惡的小手,開(kāi)啟了熟悉的操作,按下了Ctrt + 鼠標(biāo)左鍵,瞪著色咪咪的小眼睛,瞳孔放大了百倍等待著奇跡的出現(xiàn)... 擦... 擦...擦...

SpringBoot自動(dòng)裝配原理詳解

什么也沒(méi)有...那我要你有何用,這么頂級(jí)的世界級(jí)的開(kāi)源項(xiàng)目,怎么會(huì)讓一個(gè)沒(méi)用的家伙存在呢? 于是動(dòng)用了上億的腦細(xì)胞大軍,經(jīng)過(guò)復(fù)雜的運(yùn)算,得出了一個(gè)不靠譜的結(jié)論:它可能使用來(lái)標(biāo)記這是一個(gè)SpringBoot工程的配置。因?yàn)镾pringBootConfiguration翻譯過(guò)來(lái)就是SpringBoot的配置,于是心中又是幾萬(wàn)只羊駝在萬(wàn)馬奔騰,大漠飛揚(yáng)。

氣定神閑之后,秉承著·失敗是成功之母'的信念, 熟練的左手行云流水般的按下了 Ctrl + Table 鍵,回到了最初的的地方。眼睛盯著 @EnableAutoConfiguration ,環(huán)顧左右,在地址欄輸入了谷歌翻譯, 結(jié)果顯示 自動(dòng)裝配。我找的就是你,真是眾里尋他千百度,那人卻在燈火闌珊處。 熟練的按下了 Ctrl +左鍵,迫不及待的想要進(jìn)入; 心里默默背誦起了《桃花源記》的經(jīng)典詩(shī)句 ∶

林盡水源,便得一山,山有小口,仿佛若有光。便舍船,從口入。初極狹,才通人。復(fù)行數(shù)十步,豁然開(kāi)朗

SpringBoot自動(dòng)裝配原理詳解

此時(shí)此刻心情愉悅,有過(guò)前面的經(jīng)歷之后,在面對(duì)新的世界時(shí)候,我們淡定了許多。 此時(shí)大腦高速運(yùn)轉(zhuǎn),沒(méi)有再糾結(jié),直搗黃龍,進(jìn)入了 AutoConfigurationImportSelector.class 類,因?yàn)楣雀璺g告訴我們,這個(gè)是自動(dòng)配置導(dǎo)入選擇器。 于是我們發(fā)現(xiàn)了—片新天地

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;} // 獲取自動(dòng)配置的實(shí)體AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());} // 具體用來(lái)加載自動(dòng)配置類得方法protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata); // 獲取候選的配置類,即使后宮佳麗三千,也是要篩選的List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // 根據(jù)情況,自動(dòng)配置需要的配置類和不需要的配置了configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, );configurations.removeAll(exclusions);configurations = getConfigurationClassFilter().filter(configurations);fireAutoConfigurationImportEvents(configurations, exclusions); // 返回最終需要的配置return new AutoConfigurationEntry(configurations, exclusions);}}

而這個(gè)自動(dòng)配置的實(shí)體 AutoConfigurationEntry里面有兩個(gè)屬性,configurations和 exclusions。

protected static class AutoConfigurationEntry { // 用來(lái)存儲(chǔ)需要的配置項(xiàng)private final List<String> configurations; // 用來(lái)存儲(chǔ)排除的配置項(xiàng)private final Set<String> exclusions;private AutoConfigurationEntry() {this.configurations = Collections.emptyList();this.exclusions = Collections.emptySet();} }

在后面可以看到 getAutoConfigurationEntry()方法返回了一個(gè)對(duì)象 return new AutoConfigurationEntry(configurations, exclusions);這里也就是把我們需要的配置都拿到了。

那他是怎么拿到的候選的配置類呢? 我們接著看這個(gè)獲取候選配置類的方法 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);進(jìn)到方法后我們看到下面這個(gè)方法具體獲取候選配置類的方法內(nèi)容

SpringBoot自動(dòng)裝配原理詳解

這里我們跟著斷點(diǎn)去走,首先進(jìn)入getSpringFactoriesLoaderFactoryClass()方法

protected Class<?> getSpringFactoriesLoaderFactoryClass() { // 返回的是EnableAutoConfiguration字節(jié)碼對(duì)象return EnableAutoConfiguration.class;}

接著我們?cè)谶M(jìn)入getBeanClassLoader()方法,這里就是一個(gè)類加載器

protected ClassLoader getBeanClassLoader() {return this.beanClassLoader;}

最后我們?cè)谶M(jìn)入loadFactoryNames()方法,這個(gè)方法就是根據(jù)剛才的字節(jié)碼文件和類加載器來(lái)找到候選的配置類。傳遞過(guò)來(lái)的字節(jié)碼

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {ClassLoader classLoaderToUse = classLoader;if (classLoaderToUse == null) {classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();} // 獲取的EnableAutoConfiguration.class的權(quán)限定名 //org.springframework.boot.autoconfigure.EnableAutoConfigurationString factoryTypeName = factoryType.getName();return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());}

如下圖:

SpringBoot自動(dòng)裝配原理詳解

最后通過(guò)loadSpringFactories()來(lái)獲取到所有的配置類

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) { // 緩存加載的配置類Map<String, List<String>> result = cache.get(classLoader);if (result != null) {return result;} result = new HashMap<>();try { // 去資源目錄下找Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryTypeName = ((String) entry.getKey()).trim();String[] factoryImplementationNames =StringUtils.commaDelimitedListToStringArray((String) entry.getValue());for (String factoryImplementationName : factoryImplementationNames) {result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>()).add(factoryImplementationName.trim());}}}// Replace all lists with unmodifiable lists containing unique elementsresult.replaceAll((factoryType, implementations) -> implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList))); // 加載完成放到緩存中cache.put(classLoader, result);}catch (IOException ex) {throw new IllegalArgumentException('Unable to load factories from location [' +FACTORIES_RESOURCE_LOCATION + ']', ex);} // 返回加載到的配置類return result;}

這里我們要看下怎么從資源目錄下 FACTORIES_RESOURCE_LOCATION 加載的。下面是加載配置文件的路徑:

SpringBoot自動(dòng)裝配原理詳解

也就是項(xiàng)目啟動(dòng)的時(shí)候會(huì)去加載所有 META-INF 下的所有的 spring.factories 文件,我們搜一下這個(gè)這個(gè)文件,我搭建的是一個(gè)很簡(jiǎn)單的 SpringBoot 工程,它會(huì)去這幾個(gè) jar 里面找相關(guān)的配置類

SpringBoot自動(dòng)裝配原理詳解

但是最后自動(dòng)裝配的類是這個(gè)spring-boot-autoconfigure-2.4.3.RELEASE.jar

SpringBoot自動(dòng)裝配原理詳解

而根據(jù)EnabLeAutoConfiguration.class字節(jié)碼加載的配置類就只有這118自動(dòng)配置類

SpringBoot自動(dòng)裝配原理詳解

小結(jié)

實(shí)際上SpringBoot的自動(dòng)裝配原理,其實(shí)就是在項(xiàng)目啟動(dòng)的時(shí)候去加載META-INF下的 spring.factories 文件,好像也沒(méi)有那么高大上。當(dāng)然在啟動(dòng)的過(guò)程中還會(huì)有其他的配置項(xiàng)的加載,這里咱么直說(shuō)了自動(dòng)裝配的加載過(guò)程。希望對(duì)大家可以有所啟發(fā)。

以上就是SpringBoot自動(dòng)裝配原理詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot自動(dòng)裝配原理的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: ET3000双钳形接地电阻测试仪_ZSR10A直流_SXJS-IV智能_SX-9000全自动油介质损耗测试仪-上海康登 | 温控器生产厂家-提供温度开关/热保护器定制与批发-惠州市华恺威电子科技有限公司 | 中图网(原中国图书网):网上书店,尾货特色书店,30万种特价书低至2折! | 沈阳缠绕包装机厂家直销-沈阳海鹞托盘缠绕包装机价格 | Dataforth隔离信号调理模块-信号放大模块-加速度振动传感器-北京康泰电子有限公司 | 学生作文网_中小学生作文大全与写作指导 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 环压强度试验机-拉链拉力试验机-上海倾技仪器仪表科技有限公司 | 欧版反击式破碎机-欧版反击破-矿山石料破碎生产线-青州奥凯诺机械 | 技德应用| 空气净化器租赁,空气净化器出租,全国直租_奥司汀净化器租赁 | 电缆桥架生产厂家_槽式/梯式_热镀锌线槽_广东东莞雷正电气 | 胜为光纤光缆_光纤跳线_单模尾纤_光纤收发器_ODF光纤配线架厂家直销_北京睿创胜为科技有限公司 - 北京睿创胜为科技有限公司 | 大立教育官网-一级建造师培训-二级建造师培训-造价工程师-安全工程师-监理工程师考试培训 | 实验室隔膜泵-无油防腐蚀隔膜泵-耐腐蚀隔膜真空泵-杭州景程仪器 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 实验室pH计|电导率仪|溶解氧测定仪|离子浓度计|多参数水质分析仪|pH电极-上海般特仪器有限公司 | 铝箔袋,铝箔袋厂家,东莞铝箔袋,防静电铝箔袋,防静电屏蔽袋,防静电真空袋,真空袋-东莞铭晋让您的产品与众不同 | 凝胶成像仪,化学发光凝胶成像系统,凝胶成像分析系统-上海培清科技有限公司 | 山东包装,山东印刷厂,济南印刷厂-济南富丽彩印刷有限公司 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 球盟会·(中国)官方网站| 杭州画室_十大画室_白墙画室_杭州美术培训_国美附中培训_附中考前培训_升学率高的画室_美术中考集训美术高考集训基地 | 杰恒蠕动泵-蠕动泵专业厂家-19年专注蠕动泵 | 内窥镜-工业内窥镜厂家【上海修远仪器仪表有限公司】 | 哈尔滨发电机,黑龙江柴油发电机组-北方星光| 济南品牌设计-济南品牌策划-即合品牌策划设计-山东即合官网 | 空压机网_《压缩机》杂志| 油冷式_微型_TDY电动滚筒_外装_外置式电动滚筒厂家-淄博秉泓机械有限公司 | LED太阳能中国结|发光红灯笼|灯杆造型灯|节日灯|太阳能灯笼|LED路灯杆装饰造型灯-北京中海轩光电 | 真空泵维修保养,普发,阿尔卡特,荏原,卡西亚玛,莱宝,爱德华干式螺杆真空泵维修-东莞比其尔真空机电设备有限公司 | 气密性检测仪_气密性检测设备_防水测试仪_密封测试仪-岳信仪器 | SEO网站优化,关键词排名优化,苏州网站推广-江苏森歌网络 | 除甲醛公司-甲醛检测治理-杭州创绿家环保科技有限公司-室内空气净化十大品牌 | 苏州注册公司_苏州代理记账_苏州工商注册_苏州代办公司-恒佳财税 | 消防设施操作员考试报名时间,报名入口,报考条件 | 质检报告_CE认证_FCC认证_SRRC认证_PSE认证_第三方检测机构-深圳市环测威检测技术有限公司 | 无线讲解器-导游讲解器-自助讲解器-分区讲解系统 品牌生产厂家[鹰米讲解-合肥市徽马信息科技有限公司] | 超声波焊接机_超音波熔接机_超声波塑焊机十大品牌_塑料超声波焊接设备厂家 | 根系分析仪,大米外观品质检测仪,考种仪,藻类鉴定计数仪,叶面积仪,菌落计数仪,抑菌圈测量仪,抗生素效价测定仪,植物表型仪,冠层分析仪-杭州万深检测仪器网 | 热风机_工业热风机生产厂家上海冠顶公司提供专业热风机图片价格实惠 | 广西教师资格网-广西教师资格证考试网 |