Spring AOP 源碼解析(二),建立代理對象、循環依賴的代理對象如何解決

建立代理對象

接着上一篇文章,在 shouldSkip 方法中已經將 Advice 通知方法生成了 Advisor 對象而且緩存好了緩存

而後調用 getAdvicesAndAdvisorsForBean 方法去獲取當前 Bean 的攔截器(也就是 Advice 通知),這個方法首先從緩存中獲取到已經緩存好的 List<Advisor> ,而後挨個的檢查對應的 Advisor,這個方法首經過反射獲取當前類的全部的方法(包括父類)而後調用 matches 方法從 Advisor 中取出 Pointcut 表達式進行匹配檢查,只要有一個方法知足條件麼就返回爲 ture 表示須要建立代理對象ui

而後回到 AbstractAutoProxyCreator 的 wrapIfNecessary 方法中,當 specificInterceptors 不爲 null 的時候代表了須要建立代理,就會調用 createProxy 方法this

這裏又會調用 buildAdvisors 主要是對默認的一些攔截器作一些包裝和檢測3d

而後咱們回到 AbstractAutoProxyCreator 的 createProxy 方法,在最後一步會調用 proxyFactory.getProxy(getProxyClassLoader()); 來建立代理對象代理

咱們使用 AOP 的時候發現這裏的 proxyTargetClass 始終返回爲 true,它的這個值是來源於 AbstractAutoProxyCreator 的 createProxy 方法中的 proxyFactory.copyFrom(this); 這個方法,當前 this 對象是 AnnotationAwareAspectJAutoProxyCreatorcode

隨後判斷若是咱們的類若是是接口或者是一個 ProxyClass 的話就返回 JDK 動態代理對象,不然的是就返回 CGLIB 的動態代理對象cdn

到此回到 AbstractAutowireCapableBeanFactory 的 doCreateBean 的 initializeBean 方法調用中返回了代理對象對象

而後咱們返回到 AbstractFactory 的 doGetBean 方法,再看看這段邏輯blog

他不是直接調用 createBean 的是先調用了 getSingleton 方法

在這個方法中首先調用 singletonFactory.getObject 去調用 createBean 方法,而後檢測到該對象是一個新的單例對象就調用 addSingleton 放入容器中

到此建立一個完整的 Bean 實例完成了,那麼最後就還有一個問題就是,因爲須要去解決循環依賴問題,致使在調用初始化方法前其實就將 Bean 實例放入到了早期 Bean 實例中,可能會致使注入的都不是代理對象

處理循環依賴時候是如何解決代理對象問題的

好比 A 依賴 B,B 又依賴 A;同時咱們又定義了 AOP 邏輯包含到了 A 和 B 的方法它們須要被代理,前文講過首先咱們經過反射建立 A 的早期實例而後放入到 singletonFactories 中,而後再調用 populateBean 進行依賴注入的時候發現了 A 依賴於 B,這個時候就要開始 B 的實例化,這個時候在 AbstractBeanFactory 的 doGetBean 的 getSingleton 方法就能起到做用它能從 singletonFactories 建立出 A 實例來,這個時候建立出來的就是這個 A 代理對象,咱們來看下它是如何作到的接口

首先在建立 singletonFactories 的時候是放入的一個 ObjectFactory 的實現

而後的調用 singletonFactories 中的 singleFactory.getObject 方法會調用到該方法
遍歷 BeanPostProcessor 最終會調用 AnnotationAwareAspectJAutoProxyCreator 的 getEarlyBeanReference 方法

熟悉的地方又來了回到了 wrapIfNecessary 上面講過的方法中了。最後因爲 A 調用初始化方法針對代理對象來操做便可,這樣一個完整的 Bean 的實例建立就算完成了

相關文章
相關標籤/搜索