整體架構
打算開始寫這個系列,不為上首頁,也不為博取多少關注,只有一個目的:梳理知識,擴充思路;廢話不多,開始吧。第一步,大家去spring的官方github下面去下載它的源碼,具體的自己谷歌,我已經下下來了,然后spring的源碼分為下面幾個部分:
哈哈,大家是不是有一種頭暈目眩的感覺,沒事,我帶你來分析源碼,順便給自己也做個總結。第一步是要理清楚各個層級關系之間的依賴,我把圖畫好,大家自己看看就好。所有的依賴都可以在gradle文件里面找到。為了效率,建議大家在idea里面下載一個插件,叫做gradle view,可以像Maven一樣查看依賴樹。其中大家接觸的比較多的就是compile和optional了,compile對應的是當前項目的模塊,而optional對應第三方依賴。其他的我相信用過maven的人都能理解。
如果是本項目的其他模塊的話,會有一個project的關鍵字在里面,如下面的代碼,畫了思維導圖,用XMind畫的,今天就到這里吧,可累死我了。具體的XMind文件請到這里下載。大家如果想看大圖,可以右鍵在新窗口打開圖片,這樣就清楚了。
compile(project(":spring-beans")) compile(project(':spring-core'))
那么繼續,大家是不是有一種無從下手的感覺呢?有這種感覺就對了,因為你並不知道哪塊是對你重要的,我的建議就是:選依賴項少的,並且被依賴項多的模塊來作為首要模塊來進行分析,大家可以打開項目自己去看看,我個人認為spring-core這個比較核心,而且其他的很多的項目都要依賴到這個模塊,那么我們就從這個模塊入手吧。當然並不是要大家一上來就把所有的細節都研究清楚,我們現在能做的,只是把模塊和模塊之間的架構關系理清楚,還沒有深入到細節。我們打開spring-core可以發現有如下模塊:
雖然說我也不知道哪個模塊應該先去研究,不過依靠我直覺應該是core模塊,下面的分析都是基於core模塊向四周進行輻射。core包里面又有很多的子包,並且還有一堆類,雖然我現在並不知道這些類是做什么的。碰到這里,大家怎么進行分析呢?告訴大家一點方法:通過用法來進行分析,大家如果之前看過一些spring相關的文章,介紹里面的一些原理的文章,我覺得都可以回憶一下,因為這些文章所說到的思路,也許就是你正在尋找的答案。我這里是在分析架構,因為架構和架構是耦合在一起的而並非獨立的個體,所以我的敘述很可以不會按照默認順序來進行敘述,敬請理解。
AliasRegistry
Spring給這個類的一個解釋就是《通用的別名管理器》,我們想一想:Spring當中什么是別名?Qualifier注解!那么我們來尋找一下,是否這個AliasRegistry和Qualifier有什么不可告人的秘密。因為Qualifier是一個注解,所以我要找和注解相關的實現類。AnnotationConfigApplicationContext,我們首先思考一個問題:AnnotationConfigApplicationContext和AliasRegistry是否存在直接的關系呢?我們可以回到這個問題,Qualifier注解是用在什么上面的?什么?這還用問,當然是Bean上面啊!於是乎,就有了下面的答案:
AliasRegistry其實你可以理解為一個抽象基接口,其實真正的用到的接口是BeanDefinitionRegistry,那么AnnotationConfigApplicationContext其實是被GenericApplicationContext所繼承了,而GenericApplicationContext又實現了BeanDefinitionRegistry,並且這幾個唄實現的方法,其內部結構都是交給了一個BeanFactory的工廠類,也就是我們常常說到的Spring的IOC相關的思想。
@Override public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { this.beanFactory.removeBeanDefinition(beanName); } @Override public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { return this.beanFactory.getBeanDefinition(beanName); }
是不是有點迷迷糊糊了?想睡覺了?別急,我畫一張思維導圖給大家醒醒腦,具體的思維導圖可以到這里下載,如果有出錯的地方,還請各位批評指正。
像上面這么分析的話,實在是太慢了,我需要找到一個可行的方法,盡快分析。大家其實也應該想到,利用網絡,我們可以快速搜集到相關的知識點。有點小小的無奈,因為網上並沒有詳細的解答,可能是大家編程都只滿足於會用就行了吧,真的太失望了。那么我還是從我認為的比較有代表性的類來跟大家分析吧。
MethodParameter
那么大家肯定會有一個疑問,這個MethodParameter到底是做什么的呢?從下面的圖中,我們可以看到具體的子類實現,大部分是在messaging下面的。雖然說我不是很想跟大家去分析細節,不過我覺得這也是沒辦法的事情啊,因為細節就在那里,逃不掉的。
首先在這個類里面定義了一個私有的成員,叫做Executable,這個Executable可來頭不小,它是Method的父類,也就是java.lang.reflect包里面的那個我們常常用到的Method.第二個成員變量是parameterIndex,還有一個參數是nestingLevel(內嵌級別),這個參數我暫時還沒搞懂是做什么的,不過spring給出的官方解釋是:the nesting level of the target type,它有一個為1的默認值。並且這3個成員變量組成了一個構造函數。
private final Executable executable; private final int parameterIndex; private int nestingLevel = 1; public MethodParameter(Method method, int parameterIndex, int nestingLevel) { Assert.notNull(method, "Method must not be null"); this.executable = method; this.parameterIndex = validateIndex(method, parameterIndex); this.nestingLevel = nestingLevel; }
雖然我們現在還不知道這個類是做什么的,不過Java我認為有一大優勢就是它可以通過語義來猜這個類的用法,不像C++一樣指針遍地飛,找不到方向;下面的代碼就是這個類的屬性,大家也許會說,我還沒看到這個類的具體用法,我怎么可能知道這些屬性是做什么的呢?非也非也,做事就是要有探索精神,編程不能吃老本,前人的經驗固然重要,但是你的經驗,你的直覺就不重要了嗎?所以相信自己哦!
@Nullable private volatile Class<?> containingClass; @Nullable private volatile Class<?> parameterType; @Nullable private volatile Type genericParameterType;
@Nullable private volatile Annotation[] parameterAnnotations; @Nullable private volatile ParameterNameDiscoverer parameterNameDiscoverer; @Nullable private volatile String parameterName; @Nullable private volatile MethodParameter nestedMethodParameter;
我們來想這么一個問題,然后把這些問題串聯起來,我有一個Method(方法),方法里面有一些參數(MethodParameter),這些參數不止一個,它可能是第一個,第二個參數(parameterIndex),每一個參數都有一個類型object.class(parameterType),參數前面有可能加上了注解(parameterAnnotation,並且這個注解可能還有多個),這個參數有它自己的名字,因為這個方法可能是一個復雜類型,所以可能有內部類,內部類當中可能有嵌套方法參數-nestedMethodParameter(還有待考證)當然還有一種可能性就是泛型當中可能還有泛型,這樣層層嵌套,參見這篇文章,總之在答案出來之前,我不武斷認為我的就是正確的。我畫了一幅思維導圖來總結一下自己的思路。文件可以在這里下載。
再來看一張更詳細的圖,這是從AttributeAccessor接口開始的。