一、IOC(控制反轉)、AOP(切面)、DI (依賴注入)是spring的核心部分html
Spring是一種設計思想的體現,發生了「主從換位」的變化。應用程序由主動的建立對象,轉換稱了從IOC容器裏獲取對象,對象的建立、解析和註冊都由Spring來替用戶實現,用戶只管定義。spring
二、IoC容器的設計與實現--Bean組件與Context組件app
使用Spring時,它首先替咱們完成的時IOC容器的初始化,初始化的過程包括定義(BeanDefinition)、載入定義(loadBeanDefinitions,包含了解析的方法)、註冊定義(registerBeanDefinitions),註冊最後落實到代碼中就是框架
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); this.beanDefinitionMap.put(beanName, beanDefinition);
註冊到map集合中, 將BeanName做爲鍵, BeanDefinition做爲值保存。接下來看具體的源碼,加深IOC容器初始化的過程理解ui
2.1Bean組件this
bean組件在Spring的org.springframework.beans包下。IOC容器的初始化就在這個包裏完成的,定義、載入、註冊,對於使用者來講只要完成bean的定義就能夠了,其餘兩個由 Spring 在內部幫咱們完成了,對咱們來講是透明的。spa
bean的定義咱們很少說,能夠用配置文件定義bean,也能夠用註解的方式,接下來咱們看下Spring的作了那些操做:.net
2.1.2 BeanFactory概述設計
BeanFactory是Spring bean容器的根接口.提供獲取bean,是否包含bean,是否單例與原型,獲取bean類型,bean 別名的方法 。3d
2.1.3BeanFactory的繼承關係
咱們能夠看到DefaultListableBeanFactory 是最終的實現類,它實現了全部的接口,它也是Spring框架裏核心的類之一
2.1.4BeanDefinition概述
BeanDefinition是一個接口類,Bean 的定義主要由 BeanDefinition 實現,項目啓動首先是讀取bean的xml配置文件,而後解析xml文件中的各類bean的定義,將xml文件中的每個<bean />元素分別轉換解析成一個BeanDefinition對象,其中保存了從配置文件中讀取到的該bean的各類信息,之後全部的操做都是對這個對象的操做。
2.1.5 BeanDefinitionReader概述
BeanDefinitionReader一樣也是接口類,讀取xml配置文件,解析爲BeanDefinition對象過程是繁瑣的,整個解析過程主要經過下圖中的類完成:
2.1.6BeanDefinitionHolder概述
BeanDefinitionHolder是一個class實現類,BeanDefinitionHolder對象中持有的BeanDefinition實例的引用,還有beanName,還有bean的別名
先對這幾個類有個大致的瞭解,接下來從源碼中看它們實際的做用。
2.1.7Bean Definition從加載、解析、處理、註冊到BeanFactory的過程,也就是IOC容器的初始化過程
在XmlBeanDefinitionReader類中 &1.loadBeanDefinitions方法從xml文件中加載beanDefinition,將Resource轉化爲EncodedResource對象,交給它的重載方法來作加載前的準備,實際去加載xml文件的是方法doLoadBeanDefinitions(InputSource inputSource, Resource resource), public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException{ .... return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); .... } &2.doLoadBeanDefinitions方法中加載獲得一個Document對象,把Document和resource交給registerBeanDefinitions完成註冊 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource){ .... Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); .... } &3.registerBeanDefinitions(Document doc, Resource resource)方法,這裏其實是建立了一個BeanDefinitionDocumentReader對象而後讓它來完成。 public static void main(String[] args){//直接使用BeanFactory 做爲容器 String xmlPath = "applicationContext.xml"; BeanFactory factory = new XmlBeanFactory(new ClassPathResource(xmlPath)); userService = (UserService) factory.getBean("userService"); userService.add(); }
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
protected void doRegisterBeanDefinitions(Element root){
....
parseBeanDefinitions(root, this.delegate);
....
}
&3.<beans/>中還包含<bean/>元素,須要對bean元素進行解析,parseBeanDefinitions方法中調用來
parseDefaultElement方法來完成對<bean/>元素的解析,具體分解析過程有processBeanDefinition(ele, delegate)方法來實現,就是對beanDefinition的處理。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); }
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
參考: