依賴注入之Bean的例項化
阿新 • • 發佈:2019-02-15
上一篇分析到了通過遞迴的方式獲取Bean的所有依賴,接下來就該例項化Bean了。
對於例項化Bean,Spring提供了兩種方式,一種是Jdk的反射功能,還有一種就是Cglib。這兩種例項化的方式的區別是什麼呢?
依賴注入的起點是getBean方法,然後會呼叫createBean方法來實現這個過程。
進入createBean方法
resolveBeanClass方法判斷需要建立的Bean的class是否可以例項化,是否可以通過類載入器進行載入,可以看成對Class的校驗。如果Bean配置了相關的處理器,resolveBeforeInstantiation方法會返回Bean的一個代理物件,相關原理在分析依賴注入的時候會進行詳細分析。
doCreateBean是例項化Bean的方法,進入doCreateBean方法
方法中呼叫了兩個特別重要的方法,分別是createBeanInstance和populateBean。createBeanInstance用於建立Bean例項,populateBean向建立好的Bean例項中注入依賴關係。
BeanWrapper型別的物件是對建立之後的Bean物件的封裝。如果是單例的Bean,則先把快取中beanName相同的Bean刪除。
createBeanInstance方法中建立Bean的例項,方法中給出了多種生成例項的方法,比如使用工廠方法,使用帶引數的構造方法或者使用預設的建構函式的方法等。其中使用帶引數的構造方法來例項化Bean的過程非常複雜,感興趣的同志可以研究一把。所以接下來重點分析使用預設的建構函式的例項化方式。
例項化之後的Bean是Object物件的,通過這個方法,將其封裝成BeanWrapper型別的物件。進入instantiate方法。
文章開頭我們提到利用反射和Cglib的方式例項化Bean有什麼區別。區別就是如果有需要覆蓋或者動態替換的方法使用Cglib進行動態代理,如果沒有需要動態改變的方法那就直接使用反射進行例項化。所謂的動態替換或覆蓋的情況,就是使用了replace或者lookup的配置方法。這兩個方法的作用就是在呼叫目標方法的時候,對呼叫過程進行攔截,呼叫實現增強功能的攔截器,返回原來例項的代理。關於攔截和代理這部分會在AOP中進行詳細的分析。
接下來就是分別使用Jdk的反射和Cglib進行例項化的具體過程了。
熟悉反射的同志應該一眼就能看懂這個方法做了什麼。
標準的使用Enhancer例項化物件的方法,包括設定基類,回撥方法等。這個方法中出現了LookupOverrideMethodInterceptor和ReplaceOverrideMethodInterceptor兩個攔截器,作用就是攔截目標方法,實現方法增強的功能。
Bean物件已經建立好了,接下來就該進行依賴注入了。
未完待續。。。。。。