javascript
自己动手实现的 Spring IOC 和 AOP - 下篇
1. 背景
本文承接上文,來(lái)繼續(xù)說(shuō)說(shuō) IOC 和 AOP 的仿寫(xiě)。在上文中,我實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的 IOC 和 AOP 容器。上文實(shí)現(xiàn)的 IOC 和 AOP 功能很單一,且 IOC 和 AOP 兩個(gè)模塊沒(méi)有整合到一起。IOC 在加載 bean 過(guò)程中,AOP 不能對(duì) bean 織入通知。在本文中,我們?cè)敿?xì)說(shuō)一下升級(jí)版 IOC 和 AOP。這個(gè)版本的實(shí)現(xiàn)包含了在上篇中所說(shuō)的功能,這里再重述一下,如下:
上面羅列了5個(gè)功能點(diǎn),雖然看起來(lái)不多,但是對(duì)于新手來(lái)說(shuō),實(shí)現(xiàn)起來(lái)還是不很容易的。所以接下來(lái),我將圍繞上面的功能點(diǎn)展開(kāi)詳細(xì)的描述。如果大家有興趣,我還是很建議大家跟著寫(xiě)一遍,因?yàn)楹芏鄷r(shí)候能看懂,但是寫(xiě)的卻不一定能寫(xiě)出來(lái)。仿寫(xiě)一遍能夠加深對(duì) Spring IOC 和 AOP 原理的理解,多動(dòng)手是有好處的。
另外需要說(shuō)明的是,黃億華前輩實(shí)現(xiàn)的?tiny-spring?項(xiàng)目時(shí)間節(jié)點(diǎn)是 2014.1,當(dāng)時(shí)應(yīng)該是參照 Spring 3.x 版本編寫(xiě)的。部分類的設(shè)計(jì)思想可能會(huì)與現(xiàn)在最新穩(wěn)定版 4.3.10 有一定的出入,由于我暫時(shí)沒(méi)有閱讀 Spring 源碼的計(jì)劃,所以這里不能告知大家?tiny-spring?哪些類與 Spring 最新的源碼有出入,見(jiàn)諒。
好了,本章內(nèi)容先介紹到這,接下來(lái)進(jìn)入正文。
?2. IOC 的實(shí)現(xiàn)
?2.1 BeanFactory 的生命流程
上面簡(jiǎn)述了 toy-spring 項(xiàng)目的編碼背景,接下來(lái),在本節(jié)中,我將向大家介紹 toy-spring 項(xiàng)目中 IOC 部分的實(shí)現(xiàn)原理。在詳細(xì)介紹 IOC 的實(shí)現(xiàn)原理前,這里先簡(jiǎn)單說(shuō)一下 BeanFactory 的生命流程:
上面簡(jiǎn)單羅列了 BeanFactory 的生命流程,也就是 IOC 容器的生命流程。接下來(lái)就來(lái)圍繞上面的流程展開(kāi)討論。
?2.2 BeanDefinition 及其他一些類的介紹
在詳細(xì)介紹 IOC 容器的工作原理前,這里先介紹一下實(shí)現(xiàn) IOC 所用到的一些輔助類,包括BeanDefinition、BeanReference、PropertyValues、PropertyValue。這些類與接下來(lái)的 2.3 節(jié) xml 的解析緊密相關(guān)。按照順序,先從 BeanDefinition 開(kāi)始介紹。
BeanDefinition,從字面意思上翻譯成中文就是 “Bean 的定義”。從翻譯結(jié)果中就可以猜出這個(gè)類的用途,即根據(jù) Bean 配置信息生成相應(yīng)的 Bean 詳情對(duì)象。舉個(gè)例子,如果把 Bean 比作是電腦 ?,那么 BeanDefinition 就是這臺(tái)電腦的配置清單。我們從外觀上無(wú)法看出這臺(tái)電腦里面都有哪些配置,也看不出電腦的性能咋樣。但是通過(guò)配置清單,我們就可了解這臺(tái)電腦的詳細(xì)配置。我們可以知道這臺(tái)電腦是不是用了牙膏廠的 CPU,BOOM 廠的固態(tài)硬盤(pán)等。透過(guò)配置清單,我們也就可大致評(píng)估出這臺(tái)電腦的性能。
圖1 電腦和配置清單
上面那個(gè)例子還是比較貼切的,但是只是個(gè)例子,和實(shí)際還是有差距的。那么在具體實(shí)現(xiàn)中,BeanDefinition 和 xml 是怎么對(duì)應(yīng)的呢?答案在下面:
圖2 根據(jù) bean 配置生成 BeanDefinition
看完上圖,我想大家對(duì) BeanDefinition 的用途有了更進(jìn)一步的認(rèn)識(shí)。接下來(lái)我們來(lái)說(shuō)說(shuō)上圖中的 ref 對(duì)應(yīng)的 BeanReference 對(duì)象。BeanReference 對(duì)象保存的是 bean 配置中 ref 屬性對(duì)應(yīng)的值,在后續(xù) BeanFactory 實(shí)例化 bean 時(shí),會(huì)根據(jù) BeanReference 保存的值去實(shí)例化 bean 所依賴的其他 bean。
接下來(lái)說(shuō)說(shuō) PropertyValues 和 PropertyValue 這兩個(gè)長(zhǎng)的比較像的類,首先是PropertyValue。PropertyValue 中有兩個(gè)字段 name 和 value,用于記錄 bean 配置中的標(biāo)簽的屬性值。然后是PropertyValues,PropertyValues 從字面意思上來(lái)看,是 PropertyValue 復(fù)數(shù)形式,在功能上等同于 List。那么為什么 Spring 不直接使用 List,而自己定義一個(gè)新類呢?答案是要獲得一定的控制權(quán),看下面的代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class PropertyValues {private final List<PropertyValue> propertyValueList = new ArrayList<PropertyValue>();public void addPropertyValue(PropertyValue pv) {// 在這里可以對(duì)參數(shù)值 pv 做一些處理,如果直接使用 List,則就不行了this.propertyValueList.add(pv);}public List<PropertyValue> getPropertyValues() {return this.propertyValueList;}} |
好了,輔助類介紹完了,接下來(lái)我們繼續(xù) BeanFactory 的生命流程探索。
?2.3 xml 的解析
BeanFactory 初始化時(shí),會(huì)根據(jù)傳入的 xml 配置文件路徑加載并解析配置文件。但是加載和解析 xml 配置文件這種臟活累活,BeanFactory 可不太愿意干,它只想高冷的管理容器中的 bean。于是 BeanFactory 將加載和解析配置文件的任務(wù)委托給專職人員 BeanDefinitionReader 的實(shí)現(xiàn)類 XmlBeanDefinitionReader 去做。那么 XmlBeanDefinitionReader 具體是怎么做的呢?XmlBeanDefinitionReader 做了如下幾件事情:
上面的解析步驟并不復(fù)雜,實(shí)現(xiàn)起來(lái)也不難,就是解析 xml 而已,這里就不過(guò)多敘述了。
?2.4 注冊(cè) BeanPostProcessor
BeanPostProcessor 接口是 Spring 對(duì)外拓展的接口之一,其主要用途提供一個(gè)機(jī)會(huì),讓開(kāi)發(fā)人員能夠插手 bean 的實(shí)例化過(guò)程。通過(guò)實(shí)現(xiàn)這個(gè)接口,我們就可在 bean 實(shí)例化時(shí),對(duì)bean 進(jìn)行一些處理。比如,我們所熟悉的 AOP 就是在這里將切面邏輯織入相關(guān) bean 中的。正是因?yàn)橛辛?BeanPostProcessor 接口作為橋梁,才使得 AOP 可以和 IOC 容器產(chǎn)生聯(lián)系。關(guān)于這一點(diǎn),我將會(huì)在后續(xù)章節(jié)詳細(xì)說(shuō)明。
接下來(lái)說(shuō)說(shuō) BeanFactory 是怎么注冊(cè) BeanPostProcessor 相關(guān)實(shí)現(xiàn)類的。
XmlBeanDefinitionReader 在完成解析工作后,BeanFactory 會(huì)將它解析得到的 <id, BeanDefinition> 鍵值對(duì)注冊(cè)到自己的 beanDefinitionMap 中。BeanFactory 注冊(cè)好 BeanDefinition 后,就立即開(kāi)始注冊(cè) BeanPostProcessor 相關(guān)實(shí)現(xiàn)類。這個(gè)過(guò)程比較簡(jiǎn)單:
上面簡(jiǎn)述了 BeanPostProcessor 接口的用途以及注冊(cè)的過(guò)程。BeanPostProcessor 是一個(gè)比較常用接口,相信大家都很熟悉了,這里就不過(guò)多敘述了。
?2.5 getBean 過(guò)程解析
在完成了 xml 的解析、BeanDefinition 的注冊(cè)以及 BeanPostProcessor 的注冊(cè)過(guò)程后。BeanFactory 初始化的工作算是結(jié)束了,此時(shí) BeanFactory 處于就緒狀態(tài),等待外部程序的調(diào)用。
外部程序一般都是通過(guò)調(diào)用 BeanFactory 的 getBean(String name) 方法來(lái)獲取容器中的 bean。BeanFactory 具有延遲實(shí)例化 bean 的特性,也就是等外部程序需要的時(shí)候,才實(shí)例化相關(guān)的 bean。這樣做的好處是比較顯而易見(jiàn)的,第一是提高了 BeanFactory 的初始化速度,第二是節(jié)省了內(nèi)存資源。下面我們就來(lái)詳細(xì)說(shuō)說(shuō) bean 的實(shí)例化過(guò)程:
圖3 Spring bean實(shí)例化過(guò)程
上圖是一個(gè)完整的 Spring bean 實(shí)例化過(guò)程圖。在我的仿寫(xiě)項(xiàng)目中,沒(méi)有做的這么復(fù)雜,簡(jiǎn)化了 bean 實(shí)例化的過(guò)程,如下:
圖4 toy-spring bean實(shí)例化過(guò)程
接下來(lái)我將按照簡(jiǎn)化后的 bean 實(shí)例化過(guò)程介紹,如果想了解完整的 bean 實(shí)例化過(guò)程,可以參考我的另一篇文章:Spring bean的生命流程。簡(jiǎn)化后的實(shí)例化流程如下:
上面 6 步流程并不復(fù)雜,源碼實(shí)現(xiàn)的也較為簡(jiǎn)單,這里就不在貼代碼說(shuō)明了。大家如果想了解細(xì)節(jié),可以去 github 上下載?toy-spring?源碼閱讀。
?3. 實(shí)現(xiàn) AOP
?3.1 AOP 原理
AOP 是基于動(dòng)態(tài)代理模式實(shí)現(xiàn)的,具體實(shí)現(xiàn)上可以基于 JDK 動(dòng)態(tài)代理或者 Cglib 動(dòng)態(tài)代理。其中 JDK 動(dòng)態(tài)代理只能代理實(shí)現(xiàn)了接口的對(duì)象,而 Cglib 動(dòng)態(tài)代理則無(wú)此限制。所以在為沒(méi)有實(shí)現(xiàn)接口的對(duì)象生成代理時(shí),只能使用 Cglib。在 toy-spring 項(xiàng)目中,暫時(shí)只實(shí)現(xiàn)了基于 JDK 動(dòng)態(tài)代理的代理對(duì)象生成器。
關(guān)于 AOP 原理這里就不多說(shuō)了,下面說(shuō)說(shuō) toy-spring 中 AOP 的實(shí)現(xiàn)步驟。還是像上面一樣,先列流程:
對(duì)于上面的4步流程,熟悉 Spring AOP 的朋友應(yīng)該能很容易理解。如果有朋友不理解也沒(méi)關(guān)系,在后續(xù)章節(jié),我會(huì)詳細(xì)介紹相關(guān)流程的具體實(shí)現(xiàn)。
?3.2 基于 JDK 動(dòng)態(tài)代理的 AOP 實(shí)現(xiàn)
本節(jié)說(shuō)說(shuō)基于 JDK 動(dòng)態(tài)代理的代理對(duì)象生成器具體實(shí)現(xiàn)。在 toy-spring 項(xiàng)目中,代理對(duì)象生成器的邏輯主要寫(xiě)在了 JdkDynamicAopProxy 類中,這個(gè)類的有兩個(gè)方法,其中 getProxy 方法用于生成代理對(duì)象。invoke 方法是 InvocationHandler 接口的具體實(shí)現(xiàn),包含了將通知(Advice)織入相關(guān)方法中,是3.1節(jié)所列流程中第3步流程的具體實(shí)現(xiàn)。好了,接下來(lái),對(duì)著源碼講解 JdkDynamicAopProxy:
JdkDynamicAopProxy 實(shí)現(xiàn)代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public abstract class AbstractAopProxy implements AopProxy {protected AdvisedSupport advised;public AbstractAopProxy(AdvisedSupport advised) {this.advised = advised;} }/*** 基于 JDK 動(dòng)態(tài)代理的代理對(duì)象生成器* Created by code4wt on 17/8/16.*/ final public class JdkDynamicAopProxy extends AbstractAopProxy implements InvocationHandler {public JdkDynamicAopProxy(AdvisedSupport advised) {super(advised);}/*** 為目標(biāo) bean 生成代理對(duì)象* @return bean 的代理對(duì)象*/@Overridepublic Object getProxy() {return Proxy.newProxyInstance(getClass().getClassLoader(), advised.getTargetSource().getInterfaces(), this);}/*** InvocationHandler 接口中的 invoke 方法具體實(shí)現(xiàn),封裝了具體的代理邏輯* @param proxy* @param method* @param args* @return 代理方法或原方法的返回值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MethodMatcher methodMatcher = advised.getMethodMatcher();// 1. 使用方法匹配器 methodMatcher 測(cè)試 bean 中原始方法 method 是否符合匹配規(guī)則if (methodMatcher != null && methodMatcher.matchers(method, advised.getTargetSource().getTargetClass())) {// 獲取 Advice。MethodInterceptor 的父接口繼承了 AdviceMethodInterceptor methodInterceptor = advised.getMethodInterceptor();/* * 2. 將 bean 的原始方法 method 封裝在 MethodInvocation 接口實(shí)現(xiàn)類對(duì)象中,* 并把生成的對(duì)象作為參數(shù)傳給 Adivce 實(shí)現(xiàn)類對(duì)象,執(zhí)行通知邏輯*/ return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(), method, args));} else {// 2. 當(dāng)前 method 不符合匹配規(guī)則,直接調(diào)用 bean 的原始方法 methodreturn method.invoke(advised.getTargetSource().getTarget(), args);}} } |
上面貼的代碼,已經(jīng)對(duì) JdkDynamicAopProxy 實(shí)現(xiàn)代碼進(jìn)行了逐行介解釋,這里不再多說(shuō)。下面用個(gè)流程圖對(duì)通知織入邏輯進(jìn)行總結(jié):
圖5 toy-spring AOP 通知織入流程圖
最后對(duì) JdkDynamicAopProxy 進(jìn)行簡(jiǎn)單的測(cè)試,測(cè)試代碼及結(jié)果如下
測(cè)試類:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class LogInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(invocation.getMethod().getName() + " method start");Object obj= invocation.proceed();System.out.println(invocation.getMethod().getName() + " method end");return obj;} }public class JdkDynamicAopProxyTest {@Testpublic void getProxy() throws Exception {System.out.println("---------- no proxy ----------");HelloService helloService = new HelloServiceImpl();helloService.sayHelloWorld();System.out.println("\n----------- proxy -----------");AdvisedSupport advisedSupport = new AdvisedSupport();advisedSupport.setMethodInterceptor(new LogInterceptor());TargetSource targetSource = new TargetSource(helloService, HelloServiceImpl.class, HelloServiceImpl.class.getInterfaces());advisedSupport.setTargetSource(targetSource);advisedSupport.setMethodMatcher((Method method, Class beanClass) -> true);helloService = (HelloService) new JdkDynamicAopProxy(advisedSupport).getProxy();helloService.sayHelloWorld();} } |
測(cè)試結(jié)果:
為了控制文章篇幅,上面代碼中用到的其他輔助類,這里就不貼出來(lái)了,想看的朋友可以到 github 上下載源碼。
?3.3 AOP 與 IOC 協(xié)作
上一節(jié)介紹了3.1節(jié)所列流程中第3步流程的具體實(shí)現(xiàn),這一節(jié)則會(huì)介紹1、2、4步流程的具體實(shí)現(xiàn)。在介紹之前,還要再次提一下 BeanPostProcessor接口。在之前2.4節(jié) 注冊(cè) BeanPostProcessor 中我已經(jīng)介紹過(guò) BeanPostProcessor 的作用,也說(shuō)到了 AOP 是通過(guò) BeanPostProcessor 接口與 IOC 產(chǎn)生聯(lián)系的。不過(guò)2.4節(jié),只是蜻蜓點(diǎn)水提了一下,沒(méi)有詳細(xì)展開(kāi)說(shuō)明。在本節(jié)中,我將詳細(xì)講解 toy-spring 項(xiàng)目中 AOP 和 IOC 是怎樣被整合到一起的。
Spring 從2.0版本開(kāi)始集成 AspectJ,通過(guò)集成 AspectJ,也使得 Spring AOP 的功能得到了很大的增強(qiáng)。我們?cè)谄綍r(shí)開(kāi)發(fā)中,很多時(shí)候是使用基于 AspectJ 表達(dá)式及其他配置來(lái)實(shí)現(xiàn)切面功能。所以我在編寫(xiě) toy-spring 項(xiàng)目時(shí),也在項(xiàng)目中簡(jiǎn)單集成了 AspectJ。通過(guò)集成 AspectJ,使得 toy-spring AOP 可以基于 AspectJ 表達(dá)式完成復(fù)雜的匹配邏輯。接下來(lái)就讓我們看看袖珍版 Spring AOP 是怎樣實(shí)現(xiàn)的吧。
在 toy-spring 中,AOP 和 IOC 產(chǎn)生聯(lián)系的具體實(shí)現(xiàn)類是 AspectJAwareAdvisorAutoProxyCreator(下面簡(jiǎn)稱 AutoProxyCreator),這個(gè)類實(shí)現(xiàn)了 BeanPostProcessor 和 BeanFactoryAware 接口。BeanFactory 在注冊(cè) BeanPostProcessor 接口相關(guān)實(shí)現(xiàn)類的階段,會(huì)將其本身注入到 AutoProxyCreator 中,為后面 AOP 給 bean 生成代理對(duì)象做準(zhǔn)備。BeanFactory 初始化結(jié)束后,AOP 與 IOC 橋梁類 AutoProxyCreator 也完成了實(shí)例化,并被緩存在 BeanFactory 中,靜待 BeanFactory 實(shí)例化 bean。當(dāng)外部產(chǎn)生調(diào)用,BeanFactory 開(kāi)始實(shí)例化 bean 時(shí)。AutoProxyCreator 就開(kāi)始悄悄的工作了,工作細(xì)節(jié)如下:
經(jīng)過(guò)上面3步,AutoProxyCreator 就悄無(wú)聲息的把原來(lái)的 bean 替換為代理對(duì)象了,是不是有種偷天換日的感覺(jué)。最后把 toy-spring AOP 剩余的實(shí)現(xiàn)代碼貼出來(lái):
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | public class AspectJAwareAdvisorAutoProxyCreator implements BeanPostProcessor, BeanFactoryAware {private XmlBeanFactory xmlBeanFactory;@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {/* 這里兩個(gè) if 判斷很有必要,如果刪除將會(huì)使程序進(jìn)入死循環(huán)狀態(tài),* 最終導(dǎo)致 StackOverflowError 錯(cuò)誤發(fā)生*/if (bean instanceof AspectJExpressionPointcutAdvisor) {return bean;}if (bean instanceof MethodInterceptor) {return bean;}// 1. 從 BeanFactory 查找 AspectJExpressionPointcutAdvisor 類型的對(duì)象List<AspectJExpressionPointcutAdvisor> advisors =xmlBeanFactory.getBeansForType(AspectJExpressionPointcutAdvisor.class);for (AspectJExpressionPointcutAdvisor advisor : advisors) {// 2. 使用 Pointcut 對(duì)象匹配當(dāng)前 bean 對(duì)象if (advisor.getPointcut().getClassFilter().matchers(bean.getClass())) {ProxyFactory advisedSupport = new ProxyFactory();advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());TargetSource targetSource = new TargetSource(bean, bean.getClass(), bean.getClass().getInterfaces());advisedSupport.setTargetSource(targetSource);// 3. 生成代理對(duì)象,并返回return advisedSupport.getProxy();}}// 2. 匹配失敗,返回 beanreturn bean;}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws Exception {xmlBeanFactory = (XmlBeanFactory) beanFactory;} } |
ProxyFactory 實(shí)現(xiàn)代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | /*** AopProxy 實(shí)現(xiàn)類的工廠類*/ public class ProxyFactory extends AdvisedSupport implements AopProxy {@Overridepublic Object getProxy() {return createAopProxy().getProxy();}private AopProxy createAopProxy() {return new JdkDynamicAopProxy(this);} } |
測(cè)試類:
| 1 2 3 4 5 6 7 8 9 10 | public class XmlBeanFactoryTest {@Testpublic void getBean() throws Exception {System.out.println("--------- AOP test ----------");String location = getClass().getClassLoader().getResource("spring.xml").getFile();XmlBeanFactory bf = new XmlBeanFactory(location);HelloService helloService = (HelloService) bf.getBean("helloService");helloService.sayHelloWorld();} } |
測(cè)試結(jié)果:
?4. 寫(xiě)在最后
到此,本文的主要內(nèi)容寫(xiě)完了。如果你耐心的讀完了文章,并感覺(jué)不錯(cuò)的話,歡迎猛點(diǎn)贊和收藏按鈕。這篇文章花了我一天的時(shí)間,寫(xiě)的實(shí)在有點(diǎn)累,也深感認(rèn)真寫(xiě)博客的不易。本篇文章與?仿照 Spring 實(shí)現(xiàn)簡(jiǎn)單的 IOC 和 AOP - 上篇,Spring bean的生命流程?共三篇文章,對(duì) Spring IOC 和 AOP 的實(shí)現(xiàn)原理進(jìn)行了較為詳細(xì)的結(jié)束。也是通過(guò)認(rèn)真編寫(xiě)這三篇文章,使得我對(duì) Spring 框架原理有了更進(jìn)一步的認(rèn)識(shí)。當(dāng)然限于我的經(jīng)驗(yàn)和能力,以上三篇文章中可能存在著一些錯(cuò)誤。如果這些錯(cuò)誤給大家造成了干擾,我表示很抱歉。所以文章若有疏漏不妥之處,還請(qǐng)指出來(lái),如果能不吝賜教,那就更好了。好了,最后感謝大家耐心讀完我的文章,下次再見(jiàn)。
?參考:
-
《Spring揭秘》
-
tiny-spring
?附錄:Spring 源碼分析文章列表
?Ⅰ. IOC
| 2018-05-30 | Spring IOC 容器源碼分析系列文章導(dǎo)讀 |
| 2018-06-01 | Spring IOC 容器源碼分析 - 獲取單例 bean |
| 2018-06-04 | Spring IOC 容器源碼分析 - 創(chuàng)建單例 bean 的過(guò)程 |
| 2018-06-06 | Spring IOC 容器源碼分析 - 創(chuàng)建原始 bean 對(duì)象 |
| 2018-06-08 | Spring IOC 容器源碼分析 - 循環(huán)依賴的解決辦法 |
| 2018-06-11 | Spring IOC 容器源碼分析 - 填充屬性到 bean 原始對(duì)象 |
| 2018-06-11 | Spring IOC 容器源碼分析 - 余下的初始化工作 |
?Ⅱ. AOP
| 2018-06-17 | Spring AOP 源碼分析系列文章導(dǎo)讀 |
| 2018-06-20 | Spring AOP 源碼分析 - 篩選合適的通知器 |
| 2018-06-20 | Spring AOP 源碼分析 - 創(chuàng)建代理對(duì)象 |
| 2018-06-22 | Spring AOP 源碼分析 - 攔截器鏈的執(zhí)行過(guò)程 |
?Ⅲ. MVC
| 2018-06-29 | Spring MVC 原理探秘 - 一個(gè)請(qǐng)求的旅行過(guò)程 |
| 2018-06-30 | Spring MVC 原理探秘 - 容器的創(chuàng)建過(guò)程 |
- 本文鏈接:?https://www.tianxiaobo.com/2018/01/18/自己動(dòng)手實(shí)現(xiàn)的-Spring-IOC-和-AOP-下篇/
from:http://www.tianxiaobo.com/2018/01/18/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E5%AE%9E%E7%8E%B0%E7%9A%84-Spring-IOC-%E5%92%8C-AOP-%E4%B8%8B%E7%AF%87/?
總結(jié)
以上是生活随笔為你收集整理的自己动手实现的 Spring IOC 和 AOP - 下篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自己动手实现的 Spring IOC 和
- 下一篇: 基于 Zookeeper 的分布式锁实现