最新學(xué)習(xí)筆記==> 手寫RPC框架(6)-使用Netty改寫后遇到的各種坑你是否清楚
目錄
-
10個(gè)Spring&SpringBoot 高階用法修噪,相信你看完會有新的認(rèn)識
* 1查库、獲取Spring IOC容器(Aware)
* 2、動態(tài)注冊bean信息(BeanFactoryPostProcessor)
* 3黄琼、動態(tài)修改bean信息(BeanFactoryPostProcessor)
* 4樊销、獲取Spring IOC容器所有bean信息(BeanFactoryPostProcessor)
* 5整慎、為兼容不同SpringBoot 版本,以實(shí)現(xiàn)選擇性加載bean(條件注解)
* 6围苫、自定義工廠bean實(shí)例化(工廠Bean裤园、AbstractFactoryBean)
* 7、Spring MVC 輸出所有的URL信息(Spring MVC)
* 8剂府、通過Spring事件機(jī)制完成服務(wù)啟動后的信息整理(類似于Dubbo的服務(wù)暴露機(jī)制拧揽、Swagger的URL信息收集)
* 9、通過Spring事件機(jī)制獲取HTTP請求調(diào)用詳情
* 10腺占、服務(wù)啟動后的初始化任務(wù)CommandLineRunner
* 總結(jié)
【目錄】Spring&SpringBoot 實(shí)踐和源碼學(xué)習(xí)
1淤袜、獲取Spring IOC容器(Aware)
通過ApplicationContextAware實(shí)現(xiàn),在bean實(shí)例化后衰伯,經(jīng)過Aware掃描時(shí)铡羡,發(fā)現(xiàn)實(shí)現(xiàn)了ApplicationContextAware接口,就會調(diào)用setApplicationContext方法注入applicationcontext對象意鲸,這也是非常經(jīng)典的一種獲取上下文的方法烦周。
2、動態(tài)注冊bean信息(BeanFactoryPostProcessor)
通過實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口完成bean的動態(tài)注入怎顾,而且圖中的動態(tài)生成還相比一般的注冊更加復(fù)雜读慎,往其中添加了類似于@Value一般的屬性值,盡管我們后續(xù)無任何操作槐雾,Spring在進(jìn)行數(shù)據(jù)填充的時(shí)候還是成功的從Properties文件中獲取到了有效數(shù)據(jù)贪壳,這主要依靠的是PropertyPlaceHolderConfigure。
也有更簡單的方法實(shí)現(xiàn)bean的動態(tài)注冊蚜退,例如
((DefaultListableBeanFactory) beanFactory).registerBeanDefinition("school1", beanDefinition)
其實(shí)動態(tài)注冊bean非常簡單闰靴,只需要獲取到當(dāng)前的IOC容器,然后調(diào)用registerBeanDefinition即可钻注,至于獲取當(dāng)前IOC容器就可以使用Aware蚂且、BeanFactoryPostProcessor等方案。
3幅恋、動態(tài)修改bean信息(BeanFactoryPostProcessor)
上面的例子2就很好的說明了修改bean的信息杏死,在postProcessBeanDefinitionRegistry方法中實(shí)現(xiàn)了注冊操作,在postProcessBeanFactory實(shí)現(xiàn)了修改bean信息的操作捆交,再例如下面這個(gè)例子
此外可以通過類似于BeanNameAware的獲取到bean的名稱信息等
4淑翼、獲取Spring IOC容器所有bean信息(BeanFactoryPostProcessor)
利用BeanFactoryPostProcessor的postProcessBeanFactory方法,獲得當(dāng)前的IOC容器品追,然后遍歷即可玄括。
提問:BeanFactoryPostProcessor 和 BeanPostProcessor的區(qū)別在哪里,一般各自有什么用途肉瓦?
關(guān)于上面2遭京,3胃惜,4三點(diǎn)更多的原理細(xì)節(jié)可以看看
5、為兼容不同SpringBoot 版本哪雕,以實(shí)現(xiàn)選擇性加載bean(條件注解)
使用了條件注解功能船殉,獲取當(dāng)前運(yùn)行的SpringBoot版本進(jìn)行判斷,類似于系統(tǒng)自帶的條件注解斯嚎,如下圖
主要實(shí)現(xiàn)原理得看OnClassCondition類利虫,是不是感覺和@Import類似呢?
拓展:是否清楚Spring 版本升級導(dǎo)致的WebMvcConfigurerAdapter不兼容問題堡僻,那么這個(gè)基于當(dāng)前版本的條件注解功能就能很好的兼容WebMvcConfigurerAdapter問題了列吼。
條件注解原理可看 Spring 之 Condition 條件注解 實(shí)踐和源碼學(xué)習(xí)
6、自定義工廠bean實(shí)例化(工廠Bean苦始、AbstractFactoryBean)
繼承了AbstractFactoryBean抽象類寞钥,createInstance是由afterPropertiesSet方法或者getObject方法調(diào)用,想獲取具體的Student對象陌选,則需要&區(qū)分工廠bean還是包裝bean理郑,具體看下面的圖就應(yīng)該很清楚了。
此外關(guān)于afterPropertiesSet方法是InitializingBean類唯一一個(gè)方法咨油,一般用來實(shí)例化bean之后的自定義修正或者處理初始化后的其他事情您炉。如需對Spring有更深入的理解,下面這個(gè)Spring Bean生命周期的流程圖就必須清楚役电。
來源自網(wǎng)絡(luò)
拓展閱讀
7赚爵、Spring MVC 輸出所有的URL信息(Spring MVC)
關(guān)鍵思想是獲取DispatcherServlet類中的handlerMappings數(shù)據(jù),而其數(shù)據(jù)由主要是從SpringIOC容器中的HandlerMapping類bean法瑟,然后分別處理冀膝,如圖中圈出來的只有RequestMappingHandlerMapping和BeanNameUrlHandlerMapping,這是不完整的霎挟,在Spring 3.2以前是DefaultAnnotationHandlerMapping類窝剖,但是已經(jīng)被廢棄了,這里就沒有補(bǔ)充酥夭,大家在使用的時(shí)候需要知道自己Spring的版本赐纱。
如上圖運(yùn)行結(jié)果,可以看到出來熬北,除了業(yè)務(wù)的url信息疙描,還包含了actuator端點(diǎn)信息以及swagger的url信息。
Spring MVC拓展閱讀
- Spring MVC 基礎(chǔ)源碼學(xué)習(xí)
- Spring MVC 基礎(chǔ)源碼學(xué)習(xí)(續(xù))
- Spring MVC URL映射 學(xué)習(xí)(上)
- Spring MVC URL映射 學(xué)習(xí)(下)
8讶隐、通過Spring事件機(jī)制完成服務(wù)啟動后的信息整理(類似于Dubbo的服務(wù)暴露機(jī)制起胰、Swagger的URL信息收集)
也很簡單,就是使用了Spring 監(jiān)聽機(jī)制去監(jiān)聽ContextRefreshedEvent這類Spring IOC容器刷新完成之后的事件觸發(fā)整份,本demo并沒有做什么事情待错,但是結(jié)合具體業(yè)務(wù)可以做很多想做的事情,可以看看Dubbo的服務(wù)暴露接口繼承關(guān)系烈评,如下圖火俄。
本圖來自本人簡書文章截圖:http://www.reibang.com/p/507d51bf14ce
如下圖是dubbo的源碼,充分利用了監(jiān)聽機(jī)制讲冠,監(jiān)聽ContextRefreshedEvent事件瓜客,最后調(diào)用export方法完成服務(wù)暴露操作。
如果去了解Swagger的工作原理會發(fā)現(xiàn)也是類似
拓展:RPC服務(wù)結(jié)合Spring中竿开,服務(wù)暴露大體上都是依靠事件監(jiān)聽機(jī)制完成的
9谱仪、通過Spring事件機(jī)制獲取HTTP請求調(diào)用詳情
在本地測試統(tǒng)計(jì)http服務(wù)調(diào)用統(tǒng)計(jì)情況,還是很方便的否彩,依靠的是ServletRequestHandledEvent事件疯攒,默認(rèn)這個(gè)事件是開啟的,如果未開啟該事件列荔,就會導(dǎo)致事件監(jiān)聽無效敬尺。
事件機(jī)制的原理可以看看 Spring Event事件通知機(jī)制 源碼學(xué)習(xí)
10、服務(wù)啟動后的初始化任務(wù)CommandLineRunner
這個(gè)就不再介紹了贴浙,相信大家也按照上述的原理分析和學(xué)習(xí)這個(gè)工具的使用砂吞。整體的思路也是類似的。
閱讀關(guān)于SpringBoot的啟動過程了解更多 SpringBoot 啟動過程源碼分析
總結(jié)
上面幾個(gè)功能點(diǎn)說來說去就是Aware崎溃、BeanPostProcessor蜻直、BeanFactoryPostProcessor、Event袁串,而且大家如果仔細(xì)分析springboot的源碼會發(fā)現(xiàn)概而,其實(shí)整體的Spring框架并沒有太多的改進(jìn),而是依賴上述的幾種鉤子延伸和拓展囱修,單獨(dú)一個(gè)BeanPostProcessor就延伸出了多少種子類到腥,再加上Order排序,就可以非常方便的拓展功能蔚袍。
問題:如何實(shí)現(xiàn)動態(tài)路由注冊(沒有明確的Controller層定義)
最后分享一張網(wǎng)上看到的Spring的執(zhí)行流程圖解乡范,寫的確實(shí)很詳細(xì),如果希望對Spring源碼有更多深入的了解啤咽,可以好好思考和學(xué)習(xí)~