SpringFramework的核心:IOC容器的實現------Spring IOC容器概述
之前在剛開始學習的時候,我曾經嘗試過研究《Spring技術內幕》這本書,但是由於當時的經驗以及知識儲備不足。導致我沒有很好地完成閱讀這本書,這本書是對於spring原始碼的很好的分析。所以現在在我已經學完spring之後我想回顧一下,重新審視spring,從底層的角度更好地瞭解這個框架。
我曾經寫過一篇關於spring ioc容器的文章,但是當時對於spring的理解還非常膚淺,導致自己的寫的文章就像是從書上直接摘抄一樣而沒有自己的思想。所以現在我想重寫來研讀這本書並把我的一些個人感受寫出來。
在講IOC容器的實現之前,我覺得我們有必要了解一下什麼IOC到底是什麼?
IOC(Inversion of Controll)控制反轉,又叫做依賴注入。什麼意思呢。舉個例子,我們都使用過mvc模式進行過開發專案。我們需要在Controller層裡面呼叫Service層的方法,那麼我們需要在Controller層例項化一個Service層的物件。那麼我們來想一下,這個Service層的實體物件的控制權在誰的手中呢,就是Controller層,因為我們知道在Service層物件是通過new來進行例項化的。那麼這樣就會出現Controller層和Service層的程式碼耦合性過高,無法進行很好的測試。為了實現程式碼的低耦合高內聚,我們引入了依賴注入這一思想。將一個物件中所依賴的物件交給一個外部的容器或者工廠來統一進行管理。當我們的一個物件在例項化時需要獲取這其中的物件時,我們可以從外部的容器或者工廠中獲取相對應的依賴(實體)。
那麼Spring中的IOC容器有哪些呢,總體來看有兩個大類一個是BeanFactory,一個是ApplicationContext。
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&";
這是我從BeanFactory中擷取的一段程式碼,這段程式碼的意思是。我們可以使用&轉義字元獲取FactoryBean本身而不是FactoryBean的物件。
這個地方引入了FactoryBean。那麼FactoryBean和BeanFactory有什麼區別呢?
FactoryBean是一個工廠bean,它可以產生或者修飾一個物件,讓這個物件成為我們的工廠或者容器需要的物件。
BeanFactory是一個工廠,它是用來管理這些bean的。
下面我想對BeanFactory的方法進行說明:
首先關於BeanFactory,有四個getBean方法。
(1)
通過bean的名稱來獲取一個bean
Object getBean(String name) throws BeansException;
(2)通過bean的名稱以及bean的型別來獲取一個bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
(3)通過bean的型別來獲取一個bean
<T> T getBean(Class<T> requiredType) throws BeansException;
(4)通過bean的型別和傳入一些引數來獲得一個bean,這個呼叫了bean的構造方法
Object getBean(String name, Object... args) throws BeansException;
另外使用者還可以根據自己的需求做出以下操作:
1. 判斷指定名字的bean是不是單例模式
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
2.判斷指定名字的bean是不是prototype型別
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
3.判斷制定了名字的Bean的Class型別是否是特定的Class型別。
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
4.根據名字獲取bean的型別
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
5.查詢指定了名字的Bean的所有別名
String[] getAliases(String name);
這些就是關於IOC容器的簡要概述。