偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring源碼閱讀入門指引

開發(fā) 后端
本文大概的對IOC和AOP進(jìn)行了解,入門先到這一點便已經(jīng)有了大概的印象了,詳細(xì)內(nèi)容請看下文。

本文說明2點:

1.閱讀源碼的入口在哪里?

2.入門前必備知識了解:IOC和AOP

一、我們從哪里開始

1.準(zhǔn)備工作:在官網(wǎng)上下載了Spring源代碼之后,導(dǎo)入Eclipse,以方便查詢。

2.打開我們使用Spring的項目工程,找到Web.xml這個網(wǎng)站系統(tǒng)配置文件,在其中找到Spring的初始化信息:

  1. <listener> 
  2.  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
  3. </listener> 

由配置信息可知,我們開始的入口就這里ContextLoaderListener這個監(jiān)聽器。

在源代碼中我們找到了這個類,它的定義是:

  1. public class ContextLoaderListener extends ContextLoader  
  2.  implements ServletContextListener {  
  3.     …  
  4.  /**  
  5.   * Initialize the root web application context.  
  6.   */ 
  7.  public void contextInitialized(ServletContextEvent event) {  
  8.   this.contextLoader = createContextLoader();  
  9.   if (this.contextLoader == null) {  
  10.    this.contextLoader = this;  
  11.   }  
  12.   this.contextLoader.initWebApplicationContext(event.getServletContext());  
  13.  }  
  14.   ...  
  15. }  

該類繼續(xù)了ContextLoader并實現(xiàn)了監(jiān)聽器,關(guān)于Spring的信息載入配置、初始化便是從這里開始了,具體其他閱讀另外寫文章來深入了解。

二、關(guān)于IOC和AOP

關(guān)于Spring IOC 網(wǎng)上很多相關(guān)的文章可以閱讀,那么我們從中了解到的知識點是什么?

1)IOC容器和AOP切面依賴注入是Spring是核心。

IOC容器為開發(fā)者管理對象之間的依賴關(guān)系提供了便利和基礎(chǔ)服務(wù),其中Bean工廠(BeanFactory)和上下文(ApplicationContext)就是IOC的表現(xiàn)形式

BeanFactory是個接口類,只是對容器提供的最基本服務(wù)提供了定義,而DefaultListTableBeanFactory、XmlBeanFactory、ApplicationContext等都是具體的實現(xiàn)。

接口:

  1. public interface BeanFactory {  
  2.  //這里是對工廠Bean的轉(zhuǎn)義定義,因為如果使用bean的名字檢索IOC容器得到的對象是工廠Bean生成的對象,  
  3.  //如果需要得到工廠Bean本身,需要使用轉(zhuǎn)義的名字來向IOC容器檢索  
  4.  String FACTORY_BEAN_PREFIX = "&";  
  5.  //這里根據(jù)bean的名字,在IOC容器中得到bean實例,這個IOC容器就象一個大的抽象工廠,用戶可以根據(jù)名字得到需要的bean  
  6.  //在Spring中,Bean和普通的JAVA對象不同在于:  
  7.  //Bean已經(jīng)包含了我們在Bean定義信息中的依賴關(guān)系的處理,同時Bean是已經(jīng)被放到IOC容器中進(jìn)行管理了,有它自己的生命周期  
  8.  Object getBean(String name) throws BeansException;  
  9.  //這里根據(jù)bean的名字和Class類型來得到bean實例,和上面的方法不同在于它會拋出異常:如果根名字取得的bean實例的Class類型和需要的不同的話。  
  10.  Object getBean(String name, Class requiredType) throws BeansException;  
  11.  //這里提供對bean的檢索,看看是否在IOC容器有這個名字的bean  
  12.  boolean containsBean(String name);  
  13.  //這里根據(jù)bean名字得到bean實例,并同時判斷這個bean是不是單件,在配置的時候,默認(rèn)的Bean被配置成單件形式,如果不需要單件形式,需要用戶在Bean定義信息中標(biāo)注出來,這樣IOC容器在每次接受到用戶的getBean要求的時候,會生成一個新的Bean返回給客戶使用 - 這就是Prototype形式  
  14.  boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
  15.  //這里對得到bean實例的Class類型  
  16.  Class getType(String name) throws NoSuchBeanDefinitionException;  
  17.  //這里得到bean的別名,如果根據(jù)別名檢索,那么其原名也會被檢索出來  
  18.  String[] getAliases(String name);  

實現(xiàn):

XmlBeanFactory的實現(xiàn)是這樣的:

  1. public class XmlBeanFactory extends DefaultListableBeanFactory {  
  2.  //這里為容器定義了一個默認(rèn)使用的bean定義讀取器,在Spring的使用中,Bean定義信息的讀取是容器初始化的一部分,但是在實現(xiàn)上是和容器的注冊以及依賴的注入是分開的,這樣可以使用靈活的 bean定義讀取機(jī)制。  
  3.  private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);  
  4.  //這里需要一個Resource類型的Bean定義信息,實際上的定位過程是由Resource的構(gòu)建過程來完成的。  
  5.  public XmlBeanFactory(Resource resource) throws BeansException {  
  6.  this(resource, null);  
  7.  }  
  8.  //在初始化函數(shù)中使用讀取器來對資源進(jìn)行讀取,得到bean定義信息。這里完成整個IOC容器對Bean定義信息的載入和注冊過程  
  9.  public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws 
  10.  BeansException {  
  11.  super(parentBeanFactory);  
  12.  this.reader.loadBeanDefinitions(resource);  

我們可以看到IOC容器使用的一些基本過程:

如:DefaultListableBeanFactory

  1. ClassPathResource res = new ClassPathResource("beans.xml");//讀取配置文件  
  2. DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  
  3. XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);  
  4. reader.loadBeanDefinitions(res);  

這些代碼演示了以下幾個步驟:

1. 創(chuàng)建IOC配置文件的抽象資源

2. 創(chuàng)建一個BeanFactory,這里我們使用DefaultListableBeanFactory;

3. 創(chuàng)建一個載入bean定義信息的讀取器,這里使用XmlBeanDefinitionReader來載入XML形式的bean定義信息,配置給BeanFactory;

4. 從定義好的資源位置讀入配置信息,具體的解析過程由XmlBeanDefinitionReader來完成,這樣完成整個載入和注冊bean定義的過程。我們的IoC容器就建立起來了。

再簡單的說,我的系統(tǒng)在啟動時候,會完成的動作就是:

1.由ResourceLoader獲取資源文件,也即bean的各種配置文件;

2.由BeanDefintion對配置文件的定義信息的載入;

3.用BeanDefinitionRegistry接口來實現(xiàn)載入bean定義信息并向IOC容器進(jìn)行注冊。

注意,IOC容器和上下文的初始化一般不包含Bean的依賴注入的實現(xiàn)。

2)AOP這個過程并不是在注冊bean的過程實現(xiàn)的。

我們只看到在處理相關(guān)的Bean屬性的時候,使用了RuntimeBeanReference對象作為依賴信息的紀(jì)錄。

在IOC容器已經(jīng)載入了用戶定義的Bean信息前提下,這個依賴注入的過程是用戶第一次向IOC容器索要Bean的時候觸發(fā)的,或者是我們可以在Bean定義信息中通過控制lazy-init屬性來使得容器完成對Bean的預(yù)實例化 - 這個預(yù)實例化也是一個完成依賴注入的過程。

我們說明一下過程:

1.用戶想IOC容器請求Bean。

2.系統(tǒng)先在緩存中查找是否有該名稱的Bean(去各個BeanFactory去查找)

3.沒有的話就去創(chuàng)建Bean并進(jìn)行依賴注入,并且這個請求將被記錄起來。

請求Bean具體的實現(xiàn):

代碼入口在DefaultListableBeanFactory的基類AbstractBeanFactory中:

  1. public Object getBean(String name, Class requiredType, final Object[] args) throwsBeansException {  
  2. ...  
  3.  Object sharedInstance = getSingleton(beanName);//先去緩存取  
  4.  if (sharedInstance != null) {  
  5.  ...  
  6.   if (containsBeanDefinition(beanName)) {  
  7.    RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);  
  8.    bean = getObjectForBeanInstance(sharedInstance, name,mergedBeanDefinition);  
  9.   }  
  10.   else {  
  11.    bean = getObjectForBeanInstance(sharedInstance, name, null);  
  12.   }  
  13.  }  
  14.  else {  
  15.    
  16.  }  
  17.  
  18. ...  

注入Bean具體的實現(xiàn):

具體的bean創(chuàng)建過程和依賴關(guān)系的注入在createBean中,這個方法在AbstractAutowireCapableBeanFactory中給出了實現(xiàn):

  1. protected Object createBean(String beanName, RootBeanDefinition  
  2. mergedBeanDefinition, Object[] args)  
  3. throws BeanCreationException {  
  4.  // Guarantee initialization of beans that the current one depends on.  
  5.  // 這里對取得當(dāng)前bean的所有依賴bean,確定能夠取得這些已經(jīng)被確定的bean,如果沒有被創(chuàng)建,那么這個createBean會被這些IOC  
  6.  // getbean時創(chuàng)建這些bean  
  7.  if (mergedBeanDefinition.getDependsOn() != null) {  
  8.   for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {  
  9.    getBean(mergedBeanDefinition.getDependsOn()[i]);  
  10.   }  
  11.  }  
  12.  ........  
  13.  // 這里是實例化bean對象的地方,注意這個BeanWrapper類,是對bean操作的主要封裝類  
  14.  if (instanceWrapper == null) {  
  15.   instanceWrapper = createBeanInstance(beanName, mergedBeanDefinition,args);  
  16.  }  
  17.  Object bean = instanceWrapper.getWrappedInstance();  
  18.  ......  
  19.  //這個populate方法,是對已經(jīng)創(chuàng)建的bean實例進(jìn)行依賴注入的地方,會使用到在loadBeanDefinition的時候得到的那些propertyValue來對bean進(jìn)行注入。  
  20.  if (continueWithPropertyPopulation) {  
  21.   populateBean(beanName, mergedBeanDefinition, instanceWrapper);  
  22.  }  
  23.  //這里完成客戶自定義的對bean的一些初始化動作  
  24.  Object originalBean = bean;  
  25.  bean = initializeBean(beanName, bean, mergedBeanDefinition);  
  26.  // Register bean as disposable, and also as dependent on specified "dependsOn"beans.  
  27.  registerDisposableBeanIfNecessary(beanName, originalBean,mergedBeanDefinition);  
  28.  return bean;  
  29. }  
  30. .........  

這就是整個依賴注入的部分處理過程,在這個過程中起主要作用的是WrapperImp ,這個Wrapper不是一個簡單的對bean對象的封裝,因為它需要處理在beanDefinition中的信息來迭代的處理依賴注入。

到這里,這是簡單的,大概的對IOC和AOP進(jìn)行了解,入門先到這一點便已經(jīng)有了大概的印象了。

參考資料:《Spring_IOC詳解》

原文鏈接:http://blog.csdn.net/achan2090/article/details/7248043

【編輯推薦】

  1. Java多線程之消費者生產(chǎn)者模式
  2. 深入理解Java對象序列化
  3. 對于Java類加載過程中的順序問題探究
  4. 菜鳥入門Java語言學(xué)習(xí)的要點
  5. Java自定義范型的應(yīng)用技巧

 

責(zé)任編輯:林師授 來源: achan2090的博客
相關(guān)推薦

2013-12-24 10:05:04

memcached

2021-12-26 18:30:56

嵌入式ARM鏈接

2018-11-16 16:35:19

Java源碼編程語言

2017-04-05 16:40:45

2022-10-08 08:01:17

Spring源碼服務(wù)

2017-03-16 11:39:33

Openstack源碼姿勢

2018-03-28 16:10:23

閱讀源碼境界

2021-08-02 09:50:47

Vetur源碼SMART

2017-04-13 19:26:21

2021-12-20 07:58:59

GitHub源碼代碼

2014-07-29 09:44:58

jQuery源碼

2021-03-13 14:08:00

Hadoop 源碼HDFS

2009-06-26 17:34:29

Spring入門

2020-12-07 11:29:24

ReactVueVue3

2017-03-27 15:15:43

Hive源碼編譯

2023-07-10 08:43:53

SpringIDEA

2011-02-28 13:34:51

SpringMVC

2010-05-28 14:36:24

2021-01-06 05:45:58

Dubbo源碼高并發(fā)

2014-07-03 15:40:09

Apache Spar
點贊
收藏

51CTO技術(shù)棧公眾號