最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用java的spring實(shí)現(xiàn)一個(gè)簡(jiǎn)單的IOC容器示例代碼

 更新時(shí)間:2017年03月06日 10:50:01   作者:我叫了了  
本篇文章主要介紹了用java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的IOC容器示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

要想深入的理解IOC的技術(shù)原理,沒(méi)有什么能比的上我們自己實(shí)現(xiàn)它。這次我們一起實(shí)現(xiàn)一個(gè)簡(jiǎn)單IOC容器。讓大家更容易理解Spring IOC的基本原理。

這里會(huì)涉及到一些java反射的知識(shí),如果有不了解的,可以自己去找些資料看看。

注意

在上一篇文章,我說(shuō),啟動(dòng)IOC容器時(shí),Spring會(huì)將xml文件里面配置的bean掃描并實(shí)例化,其實(shí)這種說(shuō)法不太準(zhǔn)確,所以我在這里更正一下,xml文件里面配置的非單利模式的bean,會(huì)在第一次調(diào)用的時(shí)候被初始化,而不是啟動(dòng)容器的時(shí)候初始化。但是我們這次要做的例子是容器啟動(dòng)的時(shí)候就將bean初始化。特此說(shuō)明一下,害怕誤導(dǎo)初學(xué)者。

現(xiàn)在我們開(kāi)始做一個(gè)簡(jiǎn)單的IOC容器

思路:

1,啟動(dòng)容器時(shí),加載xml文件。

2,讀取xml文件內(nèi)的bean信息,并使用反射技術(shù)將bean實(shí)例化,并裝入容器。

3,確認(rèn)bean之間的以來(lái)關(guān)系,進(jìn)行注入。

下面直接上代碼,先看配置文件,與上一篇文章中使用的例子是一樣的,我們這次繼續(xù)使用上一篇文章的吃蘋(píng)果和吃橘子的例子,只不過(guò)這次我們用我們自己寫(xiě)的IOC容器,所以,我只粘貼了關(guān)鍵代碼。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!--這是吃橘子的Bean -->
  <bean id="eatOrange" class="it.spring.liao.com.EatOrange"></bean>
    <!--這是吃蘋(píng)果的Bean -->
  <bean id="eatApple" class="it.spring.liao.com.EatApple"></bean>
  <bean id="person" class="it.spring.liao.com.Person">
    <!-- 這里我們注入的是吃橘子的bean-->
    <property name="eat" ref="eatOrange"/>
  </bean>
</beans>

此處為關(guān)鍵代碼

package it.spring.liao.com;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class BeanFactory {

  // 用于存放bean實(shí)例的集合
  private Map<String, Object> beanMap = new HashMap<String, Object>();

  /**
   * bean工廠的初始化. <br>
   * 
   * @param xml
   *      配置文件路徑
   */
  public void init(String xml) {
    try {
      // 1.創(chuàng)建讀取配置文件的reader對(duì)象
      SAXReader reader = new SAXReader();
      // 2.獲取當(dāng)前線程中的類(lèi)裝載器對(duì)象
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      // 3.從class目錄下獲取指定的xml文件
      InputStream ins = classLoader.getResourceAsStream(xml);
      // 4.使用dom4j 解析xml文件
      Document doc = reader.read(ins);
      Element root = doc.getRootElement();
      // 5.初始化bean
      setBean(root);
      // 6.注入bean的依賴關(guān)系
      setPv(root);
    } catch (Exception e) {
      System.out.println(e.toString());
    }
  }

  /**
   * 初始化bean
   * 
   * @param root
   *      xml文件
   * @throws Exception
   */
  public void setBean(Element root) throws Exception {
    // 1.遍歷xml文件當(dāng)中的Bean實(shí)例
    for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
      Element foo = (Element) i.next();
      // 2.針對(duì)每個(gè)Bean實(shí)例,獲取bean的屬性id和class
      String id = foo.attribute("id").getText();
      String cls = foo.attribute("class").getText();
      // 3.利用Java反射機(jī)制,通過(guò)class的名稱獲取Class對(duì)象
      Class bean = Class.forName(cls);
      // 4.創(chuàng)建對(duì)象
      Object obj = bean.newInstance();
      // 5.將對(duì)象放入beanMap中,其中key為bean的id值,value為bean的實(shí)例
      beanMap.put(id, obj);
    }
  }

  /**
   * 注入bean的依賴關(guān)系
   * 
   * @param root
   *      xml文件
   * @throws Exception
   */
  public void setPv(Element root) throws Exception {
    for (Iterator it = root.elementIterator("bean"); it.hasNext();) {
      Element foo = (Element) it.next();

      // 1.針對(duì)每個(gè)Bean實(shí)例,獲取bean的屬性id和class
      String cls = foo.attribute("class").getText();
      String id = foo.attribute("id").getText();

      // 2.利用Java反射機(jī)制,通過(guò)class的名稱獲取Class對(duì)象
      Class bean1 = Class.forName(cls);

      // 3.獲取對(duì)應(yīng)class的信息
      java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean1);

      // 4.獲取其屬性描述
      java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();

      // 5遍歷該bean的property屬性
      for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
        Element foo2 = (Element) ite.next();

        // 6.獲取該property的name屬性
        String name = foo2.attribute("name").getText();
        String ref = foo2.attribute("ref").getText();

        // 7.在類(lèi)中尋找與xml配置文件中該bean的property屬性名相同的屬性
        for (int k = 0; k < pd.length; k++) {
          // 8.如果相等,證明已經(jīng)找到對(duì)應(yīng)得屬性
          if (pd[k].getName().equalsIgnoreCase(name)) {
            Method mSet = null;
            // 9.利用反射,獲取該屬性的set方法
            mSet = pd[k].getWriteMethod();
            // 10.用原beanMap中該bean的實(shí)例,執(zhí)行該屬性的set方法,并從原beanMap中獲取該屬性的依賴值
            mSet.invoke(beanMap.get(id), beanMap.get(ref));
          }
        }
        break;
      }
    }
  }

  /**
   * 通過(guò)bean的id獲取bean的實(shí)例
   * 
   * @param beanName
   *      bean的id
   * @return 返回對(duì)應(yīng)對(duì)象
   */
  public Object getBean(String beanName) {
    Object obj = beanMap.get(beanName);
    return obj;
  }

}




  /**
   * 測(cè)試方法.
   * 
   * @param args
   */
  public static void main(String[] args) {
    //使用我們自己寫(xiě)的 BeanFactory
    BeanFactory factory = new BeanFactory();
    factory.init("eat.xml");
    Person javaBean = (Person) factory.getBean("person");
    System.out.println(javaBean.eat()); 
  }

詳細(xì)的解釋都在代碼的注釋中,這個(gè)例子可以幫助你更深刻的理解spring的基本技術(shù)原理。但Spring的復(fù)雜程度遠(yuǎn)遠(yuǎn)高于這個(gè)例子,再說(shuō)一次,spring IOC中使用懶加載機(jī)制,在啟動(dòng)spring IOC時(shí),只會(huì)實(shí)例化單例模式的bean,不會(huì)實(shí)例化普通的bean,關(guān)于單例模式還是其他模式,是可以自己配置的,我們會(huì)在后面的文章中講解,非單例模式bean的實(shí)例化,發(fā)生在第一次調(diào)用的時(shí)候,與我們這個(gè)例子不太一樣。這個(gè)例子只供了解Spring IOC的基本原理,真實(shí)情況要復(fù)雜的多,需要我們一點(diǎn)點(diǎn)的去學(xué)習(xí),不積跬步無(wú)以至千里。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 自己動(dòng)手在Spring-Boot上加強(qiáng)國(guó)際化功能的示例

    自己動(dòng)手在Spring-Boot上加強(qiáng)國(guó)際化功能的示例

    這篇文章主要介紹了自己動(dòng)手在Spring-Boot上加強(qiáng)國(guó)際化功能的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • 淺析Spring Security登錄驗(yàn)證流程源碼

    淺析Spring Security登錄驗(yàn)證流程源碼

    這篇文章主要介紹了Spring Security登錄驗(yàn)證流程源碼解析,本文結(jié)合源碼講解登錄驗(yàn)證流程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Redis高并發(fā)場(chǎng)景防止庫(kù)存數(shù)量超賣(mài)少賣(mài)

    Redis高并發(fā)場(chǎng)景防止庫(kù)存數(shù)量超賣(mài)少賣(mài)

    商品超賣(mài)是銷(xiāo)售數(shù)量超過(guò)實(shí)際庫(kù)存的情況,常因庫(kù)存管理不當(dāng)引發(fā),傳統(tǒng)庫(kù)存管理在高并發(fā)環(huán)境下易出錯(cuò),可通過(guò)線程加鎖或使用Redis同步庫(kù)存狀態(tài)解決,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-09-09
  • SpringBoot整合Sharding-JDBC實(shí)現(xiàn)MySQL8讀寫(xiě)分離

    SpringBoot整合Sharding-JDBC實(shí)現(xiàn)MySQL8讀寫(xiě)分離

    本文是一個(gè)基于SpringBoot整合Sharding-JDBC實(shí)現(xiàn)讀寫(xiě)分離的極簡(jiǎn)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-07-07
  • Java的Shiro框架認(rèn)證流程詳解

    Java的Shiro框架認(rèn)證流程詳解

    這篇文章主要介紹了Java的Shiro框架認(rèn)證流程詳解,Shiro 是一個(gè)功能強(qiáng)大和易于使用的安全框架,為開(kāi)發(fā)人員提供一個(gè)直觀而全面的解決方案的認(rèn)證,授權(quán),加密,會(huì)話管理四大功能,需要的朋友可以參考下
    2024-01-01
  • Java設(shè)計(jì)模式中的單例模式解析

    Java設(shè)計(jì)模式中的單例模式解析

    這篇文章主要介紹了Java設(shè)計(jì)模式中的單例模式解析,單例模式確保一個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,需要的朋友可以參考下
    2023-11-11
  • Java中避免空指針異常的方法

    Java中避免空指針異常的方法

    這篇文章主要介紹了Java中避免空指針異常的方法,本文討論Optional類(lèi)型、Objects類(lèi)等技術(shù),需要的朋友可以參考下
    2014-10-10
  • Java中如何檢查數(shù)組是否包含某整數(shù)

    Java中如何檢查數(shù)組是否包含某整數(shù)

    這篇文章主要介紹了在?Java?中檢查數(shù)組是否包含某整數(shù),在本文中,我們使用了幾個(gè)內(nèi)置的方法,如anyMatch()、contains()、binarySearch()等,我們將在給定的數(shù)組中找到一個(gè)值,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Maven?自動(dòng)化構(gòu)建的實(shí)現(xiàn)示例

    Maven?自動(dòng)化構(gòu)建的實(shí)現(xiàn)示例

    本文主要介紹了Maven?自動(dòng)化構(gòu)建的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • MAVEN的安裝配置與IDEA整合超詳細(xì)教程

    MAVEN的安裝配置與IDEA整合超詳細(xì)教程

    這篇文章給大家介紹了MAVEN的安裝,配置與IDEA整合方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,感興趣的朋友跟隨小編一起看看吧
    2021-02-02

最新評(píng)論

渭源县| 三穗县| 新昌县| 唐山市| 札达县| 溧水县| 通江县| 崇信县| 白河县| 德昌县| 潼南县| 盐源县| 大港区| 乐至县| 陆良县| 河源市| 论坛| 科尔| 开江县| 西乡县| 扶绥县| 利辛县| 宁德市| 霞浦县| 蒲城县| 托里县| 广河县| 临漳县| 平乐县| 仙居县| 华亭县| 临泉县| 阆中市| 芜湖县| 礼泉县| 舒兰市| 西宁市| 景宁| 天台县| 双牌县| 宁城县|