日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Ioc 源码分析(一)--Spring Ioc容器的加载

發布時間:2025/3/18 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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繼承實現關系

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { // DefaultListableBeanFactory的實例中最終保存了所有注冊的bean beanDefinitionMap/** Map of bean definition objects, keyed by bean name */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64); //實現BeanDefinitionRegistry中定義的registerBeanDefinition()抽象方法public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {}

>2.BeanDefinitionRegistry接口

public interface BeanDefinitionRegistry extends AliasRegistry { //定義注冊BeanDefinition實例的抽象方法void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;

4.實例化


注冊也完成之后,在BeanFactory的getBean()方法之中,會完成初始化,也就是依賴注入的過程
大體上的流程就是這樣,下一篇博客,再具體地從代碼層面進行介紹。

博客搬家:大坤的個人博客
歡迎評論哦~

總結

以上是生活随笔為你收集整理的Spring Ioc 源码分析(一)--Spring Ioc容器的加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。