簡(jiǎn)單模擬Spring
生命不息,寫作不止 繼續(xù)踏上學(xué)習(xí)之路,學(xué)之分享筆記 總有一天我也能像各位大佬一樣 一個(gè)有夢(mèng)有戲的人 @怒放吧德德分享學(xué)習(xí)心得,歡迎指正,大家一起學(xué)習(xí)成長(zhǎng)!上次已經(jīng)學(xué)習(xí)了Java的設(shè)計(jì)模式,接下來(lái)就先來(lái)學(xué)習(xí)一下如何手寫模擬簡(jiǎn)易的Spring,通過(guò)動(dòng)手實(shí)踐,才會(huì)更好的了解spring底層原理,今天就簡(jiǎn)單的模擬Spring容器是如何創(chuàng)建,bean又是如何注入的 。來(lái)看一下本次案例的spring類圖

文章插圖
Spring容器模擬spring,首先就是需要一個(gè)容器,是Spring的核心,一切Spring bean都存儲(chǔ)在Spring容器內(nèi),并由其通過(guò)IoC技術(shù)管理 。Spring容器也就是一個(gè)bean工廠(BeanFactory) 。應(yīng)用中bean的實(shí)例化,獲取,銷毀等都是由這個(gè)bean工廠管理的 。就像我們剛開(kāi)始學(xué)習(xí)的時(shí)候接觸的ApplicationContext,就是spring的容器,他就是為了完成容器的配置,初始化,管理bean的 。因此筆者自己創(chuàng)建了一個(gè)LydApplicationContext來(lái)模擬簡(jiǎn)單的spring容器 。
開(kāi)始使用首先通過(guò)new LydApplicationContext(AppConfig.class)實(shí)例化對(duì)象,在通過(guò)applicationContext.getBean("userService")去獲得bean對(duì)象 。然而在容器的初始化可是做了許多的事情,包括掃描、實(shí)例化bean等等操作 。初始容器創(chuàng)建:
public class LydApplicationContext { private Class configClass; public LydApplicationContext(Class configClass) { // 構(gòu)造方法 this.configClass = configClass; }}Spring掃描底層實(shí)現(xiàn)Spring容器建好之后我們就需要通過(guò)配置文件的注解獲取掃描路徑,我們需要獲取所有的bean,并且需要實(shí)例對(duì)象 。在此我們需要一個(gè)配置文件,就是使用new LydApplicationContext(AppConfig.class) 實(shí)例攜帶的配置類,當(dāng)然這里有好多的形式,也可以是通過(guò)xml文件來(lái)處理 。
配置文件AppConfig.java這個(gè)就是為了提供掃描的包路徑的,不做任何操作,所以不需要其他代碼 。
@ComponentScan("com.lyd.service") // 掃描路徑,掃描這個(gè)包下的public class AppConfig {}通過(guò)注解存放這個(gè)包路徑,在后面可以通過(guò)這個(gè)注解來(lái)獲取包路徑,所以就需要我們創(chuàng)建一個(gè)ComponentScan注解 。
編寫ComponentScan注解這個(gè)注解是用來(lái)spring容器掃描包為之提供包路徑 。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface ComponentScan { // 指定掃描路徑 String value() default "";}編寫Component注解在Spring中,通過(guò)Component注解將bean注入Spring容器中,這里我們也采用高這個(gè)注解 。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Component { String value() default "";}獲取包路徑既然已經(jīng)通過(guò)注解將包路徑存在配置類中,接下來(lái)就可以通過(guò)這個(gè)注解來(lái)得到 。但是,在這里需要注意的是,我們掃描的并非是java源文件,而是編譯后的class文件 。我們需要在LydApplicationContext的構(gòu)造方法中去實(shí)現(xiàn) 。首先,我們需要通過(guò)isAnnotationPresent方法先判斷是否存在ComponentScan注解,在通過(guò)類的getAnnotation方法來(lái)得到注解 。這樣就可以直接得到注解上的值 。這個(gè)值就是我們寫入的包路徑,注意,這里的路徑是com.lyd.service,而我們需要用替換方法將'.'替換成'/',因?yàn)樵诤竺娅@取資源路徑的時(shí)候,用的是com/lyd/service這種形式,也就是相對(duì)路徑 。接下來(lái)需要獲取資源路徑,這個(gè)時(shí)候就需要用到類加載器LydApplicationContext.class.getClassLoader(),類加載器中有一個(gè)getResource(path)方法,這個(gè)可以根據(jù)傳入的路徑獲取相應(yīng)的資源,最后是能夠拼出我們需要的絕對(duì)路徑 。
經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀
- 冰的熔點(diǎn)是多少
- 【ASP.NET Core】MVC控制器的各種自定義:應(yīng)用程序約定的接口與模型
- 基礎(chǔ)版 【網(wǎng)絡(luò)】?jī)?nèi)網(wǎng)穿透方案&FRP內(nèi)網(wǎng)穿透實(shí)戰(zhàn)
- 金線蓮的吃法
- 2023年9月6日是疏通管道吉日嗎 2023年9月6日適合疏通管道嗎
- 半畝是多少
- 銀耳可以泡一晚上再煮嗎
- 熊貓便便有什么用
- 清除青苔最有效的方法
- 油是導(dǎo)體還是絕緣體
