<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小菜毛毛技術分享

    與大家共同成長

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
    看到這個標題大家可能又想:哎,又一個重新發明輪子的人。在這里很想先聲明一下,寫這篇文章只是想讓大家了解一下Spring到底是怎么運行的,并不是想重造輪子噢,希望大家看完這篇文章后能對Spring有更深入的了解,希望這篇文章對你有所幫助喔!好,言歸正傳,讓我們來一起探索吧!
    我們先從最常見的例子開始吧
    Java代碼 復制代碼
    1. public static void main(String[] args) {   
    2.         ApplicationContext context = new FileSystemXmlApplicationContext(   
    3.                 "applicationContext.xml");   
    4.         Animal animal = (Animal) context.getBean("animal");   
    5.         animal.say();   
    6.     }  

    這段代碼你一定很熟悉吧,不過還是讓我們分析一下它吧,首先是applicationContext.xml
    Java代碼 復制代碼
    1. <bean id="animal" class="phz.springframework.test.Cat">   
    2.         <property name="name" value="kitty" />   
    3.     </bean>  

    他有一個類phz.springframework.test.Cat
    Java代碼 復制代碼
    1. public class Cat implements Animal {   
    2.     private String name;   
    3.     public void say() {   
    4.         System.out.println("I am " + name + "!");   
    5.     }   
    6.     public void setName(String name) {   
    7.         this.name = name;   
    8.     }   
    9. }  

    實現了phz.springframework.test.Animal接口
    Java代碼 復制代碼
    1. public interface Animal {   
    2.     public void say();   
    3. }  

    很明顯上面的代碼輸出I am kitty!

    那么到底Spring是如何做到的呢?
    接下來就讓我們自己寫個Spring 來看看Spring 到底是怎么運行的吧!

    首先,我們定義一個Bean類,這個類用來存放一個Bean擁有的屬性
    Java代碼 復制代碼
    1. /* Bean Id */  
    2.     private String id;   
    3.     /* Bean Class */  
    4.     private String type;   
    5.     /* Bean Property */  
    6.     private Map<String, Object> properties = new HashMap<String, Object>();  

    一個Bean包括id,type,和Properties。

    接下來Spring 就開始加載我們的配置文件了,將我們配置的信息保存在一個HashMap中,HashMap的key就是Bean 的 Id ,HasMap 的value是這個Bean,只有這樣我們才能通過context.getBean("animal")這個方法獲得Animal這個類。我們都知道Spirng可以注入基本類型,而且可以注入像List,Map這樣的類型,接下來就讓我們以Map為例看看Spring是怎么保存的吧

    Map配置可以像下面的
    Java代碼 復制代碼
    1. <bean id="test" class="Test">   
    2.         <property name="testMap">   
    3.             <map>   
    4.                 <entry key="a">   
    5.                     <value>1</value>   
    6.                 </entry>   
    7.                 <entry key="b">   
    8.                     <value>2</value>   
    9.                 </entry>   
    10.             </map>   
    11.         </property>   
    12.     </bean>  

    Spring是怎樣保存上面的配置呢?,代碼如下:
    Java代碼 復制代碼
    1. if (beanProperty.element("map") != null) {   
    2.                     Map<String, Object> propertiesMap = new HashMap<String, Object>();   
    3.                     Element propertiesListMap = (Element) beanProperty   
    4.                             .elements().get(0);   
    5.                     Iterator<?> propertiesIterator = propertiesListMap   
    6.                             .elements().iterator();   
    7.                     while (propertiesIterator.hasNext()) {   
    8.                         Element vet = (Element) propertiesIterator.next();   
    9.                         if (vet.getName().equals("entry")) {   
    10.                             String key = vet.attributeValue("key");   
    11.                             Iterator<?> valuesIterator = vet.elements()   
    12.                                     .iterator();   
    13.                             while (valuesIterator.hasNext()) {   
    14.                                 Element value = (Element) valuesIterator.next();   
    15.                                 if (value.getName().equals("value")) {   
    16.                                     propertiesMap.put(key, value.getText());   
    17.                                 }   
    18.                                 if (value.getName().equals("ref")) {   
    19.                                     propertiesMap.put(key, new String[] { value   
    20.                                             .attributeValue("bean") });   
    21.                                 }   
    22.                             }   
    23.                         }   
    24.                     }   
    25.                     bean.getProperties().put(name, propertiesMap);   
    26.                 }  


    接下來就進入最核心部分了,讓我們看看Spring 到底是怎么依賴注入的吧,其實依賴注入的思想也很簡單,它是通過反射機制實現的,在實例化一個類時,它通過反射調用類中set方法將事先保存在HashMap中的類屬性注入到類中。讓我們看看具體它是怎么做的吧。
    首先實例化一個類,像這樣
    Java代碼 復制代碼
    1. public static Object newInstance(String className) {   
    2.         Class<?> cls = null;   
    3.         Object obj = null;   
    4.         try {   
    5.             cls = Class.forName(className);   
    6.             obj = cls.newInstance();   
    7.         } catch (ClassNotFoundException e) {   
    8.             throw new RuntimeException(e);   
    9.         } catch (InstantiationException e) {   
    10.             throw new RuntimeException(e);   
    11.         } catch (IllegalAccessException e) {   
    12.             throw new RuntimeException(e);   
    13.         }   
    14.         return obj;   
    15.     }  

    接著它將這個類的依賴注入進去,像這樣
    Java代碼 復制代碼
    1. public static void setProperty(Object obj, String name, String value) {   
    2.         Class<? extends Object> clazz = obj.getClass();   
    3.         try {   
    4.             String methodName = returnSetMthodName(name);   
    5.             Method[] ms = clazz.getMethods();   
    6.             for (Method m : ms) {   
    7.                 if (m.getName().equals(methodName)) {   
    8.                     if (m.getParameterTypes().length == 1) {   
    9.                         Class<?> clazzParameterType = m.getParameterTypes()[0];   
    10.                         setFieldValue(clazzParameterType.getName(), value, m,   
    11.                                 obj);   
    12.                         break;   
    13.                     }   
    14.                 }   
    15.             }   
    16.         } catch (SecurityException e) {   
    17.             throw new RuntimeException(e);   
    18.         } catch (IllegalArgumentException e) {   
    19.             throw new RuntimeException(e);   
    20.         } catch (IllegalAccessException e) {   
    21.             throw new RuntimeException(e);   
    22.         } catch (InvocationTargetException e) {   
    23.             throw new RuntimeException(e);   
    24.         }   
    25. }  

    最后它將這個類的實例返回給我們,我們就可以用了。我們還是以Map為例看看它是怎么做的,我寫的代碼里面是創建一個HashMap并把該HashMap注入到需要注入的類中,像這樣,
    Java代碼 復制代碼
    1. if (value instanceof Map) {   
    2.                 Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()   
    3.                         .iterator();   
    4.                 Map<String, Object> map = new HashMap<String, Object>();   
    5.                 while (entryIterator.hasNext()) {   
    6.                     Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();   
    7.                     if (entryMap.getValue() instanceof String[]) {   
    8.                         map.put((String) entryMap.getKey(),   
    9.                                 getBean(((String[]) entryMap.getValue())[0]));   
    10.                     }   
    11.                 }   
    12.                 BeanProcesser.setProperty(obj, property, map);   
    13.             }  

    好了,這樣我們就可以用Spring 給我們創建的類了,是不是也不是很難啊?當然Spring能做到的遠不止這些,這個示例程序僅僅提供了Spring最核心的依賴注入功能中的一部分。
    本文參考了大量文章無法一一感謝,在這一起感謝,如果侵犯了你的版權深表歉意,很希望對大家有幫助!

    附件中包含該山寨Spring的源碼,核心只有五個類,還有一個測試程序,phz.springframework.test.AnimalSayApp,可以直接運行。
    posted on 2010-03-04 16:28 小菜毛毛 閱讀(2847) 評論(1)  編輯  收藏 所屬分類: 面試

    Feedback

    # re: spring 注入原理 2014-06-10 23:29 vanlz
    能自己寫出這段最起碼得兩年  回復  更多評論
      

    主站蜘蛛池模板: 91成人在线免费视频| 伊人久久综在合线亚洲91| 粉色视频成年免费人15次| 中文字幕第一页亚洲| 91香蕉国产线在线观看免费| 亚洲私人无码综合久久网| 国产成人麻豆亚洲综合无码精品| 曰批全过程免费视频网址| 日韩亚洲人成网站| 久久久婷婷五月亚洲97号色| 国产成人免费福利网站| 久久免费视频99| 黄色免费网站在线看| 亚洲网站在线免费观看| 亚洲成av人片不卡无码久久| 日韩精品无码一区二区三区免费| 国产精品自拍亚洲| 亚洲春黄在线观看| 亚洲桃色AV无码| 四虎影在线永久免费四虎地址8848aa| 久久免费精品视频| 日本中文字幕免费看| 亚洲AV色吊丝无码| 亚洲AV成人片色在线观看高潮| 国产成人免费ā片在线观看| 亚洲综合免费视频| 三级网站免费观看| 黄色免费网站在线看| 学生妹亚洲一区二区| 亚洲欧洲国产日韩精品| 亚洲人成人网站在线观看| 在线观看人成网站深夜免费| 99免费观看视频| 中国在线观看免费的www| 亚洲AV无码一区二区三区网址| 亚洲欧洲久久精品| 亚洲bt加勒比一区二区| 亚洲精品无码乱码成人| 亚洲国产aⅴ综合网| 国产免费拔擦拔擦8x| 午夜一级毛片免费视频|