javascript
Spring Ioc 源码分析(一)--Spring Ioc容器的加载
1.目標:熟練使用spring,并分析其源碼,了解其中的思想。這篇主要介紹spring ioc 容器的加載
2.前提條件:會使用debug
3.源碼分析方法:Intellj idea debug 模式下源碼追溯
通過ClassPathXmlApplicationContext 進行xml 件的讀取,從每個堆棧中讀取程序的運行信息
4.注意:由于Spring的類繼承體系比較復雜,不能全部貼圖,所以只將分析源碼之后發現的最主要的類繼承結構類圖貼在下方。
5.關于Spring Ioc Demo:我們從demo入手一步步進行代碼追溯。
1.Spring Ioc Demo
1.定義數據訪問接口IUserDao.java
public interface IUserDao { public void InsertUser(String username,String password); }2.定義IUserDao.java實現類IUserDaoImpl.java
public class UserDaoImpl implements IUserDao { @Override public void InsertUser(String username, String password) { System.out.println("----UserDaoImpl --addUser----"); } }3.定義業務邏輯接口UserService.java
public interface UserService { public void addUser(String username,String password); }4.定義UserService.java實現類UserServiceImpl.java
public class UserServiceImpl implements UserService { private IUserDao userDao; //set方法 public void setUserDao(IUserDao userDao) { this.userDao = userDao; } @Override public void addUser(String username,String password) { userDao.InsertUser(username,password); } }bean.xml配置文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <!--id名字自己取,class表示他代表的類,如果在包里的話需要加上包名--> <bean id="userService" class="UserServiceImpl" > <!--property代表是通過set方法注入,ref的值表示注入的內容--><property name="userDao" ref="userDao"/> </bean> <bean id="userDao" class="UserDaoImpl"/> </beans>2.ApplicationContext 繼承結構:
1.頂層接口:ApplicationContext
2.ClassPathXmlApplicationContext實現類繼承AbstractXmlApplication 抽象類
3.AbstractXmlApplication 繼承AbstractRefreshableConfigApplicationContext
4.AbstractRefreshableConfigApplicationContext抽象類繼承AbstractRefreshableApplicationContext
5.AbstractRefreshableApplicationContext 繼承 AbstractApplicationContext
6.AbstractApplicationContext 實現ConfigurableApplicationContext 接口
7.ConfigurableApplicationContext 接口繼承
ApplicationContext接口
總體來說繼承實現結構較深,內部使用了大量適配器模式。
以ClassPathXmlApplicationContext為例,繼承類圖如下圖所示:
Spring ioc .png
3.Spring Ioc容器加載過程源碼詳解
在開始之前,先介紹一個整體的概念。即spring ioc容器的加載,大體上經過以下幾個過程:
資源文件定位、解析、注冊、實例化
1.資源文件定位
其中資源文件定位,一般是在ApplicationContext的實現類里完成的,因為ApplicationContext接口繼承ResourcePatternResolver 接口,ResourcePatternResolver接口繼承ResourceLoader接口,ResourceLoader其中的getResource()方法,可以將外部的資源,讀取為Resource類。
2.解析DefaultBeanDefinitionDocumentReader,
解析主要是在BeanDefinitionReader中完成的,最常用的實現類是XmlBeanDefinitionReader,其中的loadBeanDefinitions()方法,負責讀取Resource,并完成后續的步驟。ApplicationContext完成資源文件定位之后,是將解析工作委托給XmlBeanDefinitionReader來完成的
解析這里涉及到很多步驟,最常見的情況,資源文件來自一個XML配置文件。首先是BeanDefinitionReader,將XML文件讀取成w3c的Document文檔。
DefaultBeanDefinitionDocumentReader對Document進行進一步解析。然后DefaultBeanDefinitionDocumentReader又委托給BeanDefinitionParserDelegate進行解析。如果是標準的xml namespace元素,會在Delegate內部完成解析,如果是非標準的xml namespace元素,則會委托合適的NamespaceHandler進行解析最終解析的結果都封裝為BeanDefinitionHolder,至此解析就算完成。
后續會進行細致講解。
3.注冊
然后bean的注冊是在BeanFactory里完成的,BeanFactory接口最常見的一個實現類是DefaultListableBeanFactory,它實現了BeanDefinitionRegistry接口,所以其中的registerBeanDefinition()方法,可以對BeanDefinition進行注冊這里附帶一提,最常見的XmlWebApplicationContext不是自己持有BeanDefinition的,它繼承自AbstractRefreshableApplicationContext,其持有一個DefaultListableBeanFactory的字段,就是用它來保存BeanDefinition
所謂的注冊,其實就是將BeanDefinition的name和實例,保存到一個Map中。剛才說到,最常用的實現DefaultListableBeanFactory,其中的字段就是beanDefinitionMap,是一個ConcurrentHashMap。
代碼如下:
>1.DefaultListableBeanFactory繼承實現關系
>2.BeanDefinitionRegistry接口
public interface BeanDefinitionRegistry extends AliasRegistry { //定義注冊BeanDefinition實例的抽象方法void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;4.實例化
注冊也完成之后,在BeanFactory的getBean()方法之中,會完成初始化,也就是依賴注入的過程
大體上的流程就是這樣,下一篇博客,再具體地從代碼層面進行介紹。
博客搬家:大坤的個人博客
歡迎評論哦~
總結
以上是生活随笔為你收集整理的Spring Ioc 源码分析(一)--Spring Ioc容器的加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php学习的路线图
- 下一篇: 哪些CSS是可以被继承的--简单整理