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

Spring的Ioc模擬實現(xiàn)詳細介紹

 更新時間:2017年11月01日 16:59:57   作者:C_凱  
這篇文章主要介紹了Spring的Ioc模擬實現(xiàn)詳細介紹,具有一定參考價值,需要的朋友可以了解下。

簡單來說就是當自己需要一個對象的時候不需要自己手動去new一個,而是由其他容器來幫你提供;Spring里面就是IOC容器。

例如:

在Spring里面經(jīng)常需要在Service這個裝配一個Dao,一般是使用@Autowired注解:類似如下

public Class ServiceImpl{
  @Autowired
   Dao dao;
   
  public void getData(){
    dao.getData();
  }

在這里未初始化Dao直接使用是會報出空指針異常的,那么在Spring里面的做法就是通過反射來將需要的類幫你加載進來。

關于IOC:我們講個故事吧!

有一個廚師,他在做一道菜的時候需要某種調(diào)味料(bean),可是他正好沒有那瓶調(diào)味料(bean),這個時候他就必須去制作一瓶調(diào)味料(bean)出來。(這就像我們平時需要對象的時候一樣:UserDao  userdao=new UserDaoImpl)這個時候廚師的工作就不得不跟制作調(diào)味料聯(lián)系起來,這就是所謂的“耦合”。(耦合程度高通說來說就是,我沒了你我活不了了。);

這個時候IOC里的控制反轉(zhuǎn)出來了,它提出,開辟一個倉庫(容器),里面放著各種各樣的調(diào)味料(bean),當你需要某種調(diào)味料(bean)的時候只要給出調(diào)味料的名字(beanName)就可以直接去拿取,代碼類似這樣:(UserDao user=倉庫.get("調(diào)味料名字"));這樣你就可以直接拿到了調(diào)味料 (bean)而不用等到你沒有的時候再去制作一瓶出來。這就是所謂的將控制權轉(zhuǎn)移出來,它將生產(chǎn)調(diào)味料(bean)的工作直接讓倉庫(容器)來制作(生產(chǎn));

接下來依賴注入出來了,它就更加地強大的了,它提出廚師只要有一個瓶子(private UserDao userdao),并且將瓶子蓋打開(方法:setUserDao( UserDao userdao){this.userdao=userdao}即提供對于的set方法 )再給瓶子貼上一個標簽注明要放什么材料(在xml文件中配置一下<property name="userdao",ref="xxbean"),那么這個時候你什么都不用做了,倉庫(容器)會自動派人幫你將你所需的調(diào)味料(bean)放入到瓶子中 ;當你想換另一種調(diào)味料的時候只要將瓶子上的標簽改成其他比如胡椒粉(這時要在xml文件中更改一下ref的bean就行了),依賴注入提高了代碼的靈活性,你需要替換類的實現(xiàn)的時候,不需要去修改只要在xml配置文件里修改一下就行了;

總結一下我的總結:IOC的主要目的就是實現(xiàn)解耦!解耦!解耦!重要的事情說三遍.由廚師的列子來說就是.我是一個廚師我只做菜,我不做調(diào)味料~~我不是一個做調(diào)味料的,我不跟制作調(diào)味料有那么大的關系.   IOC的出現(xiàn),廚師只要安心做好自己的事情(做菜),需要調(diào)味料直接去倉庫拿取就行了!那么這樣廚師跟調(diào)味料的制作之間的關系就分離開來了,這就是解耦!解耦!解耦!使兩個東西的關系沒那么緊密.

模擬IOC的實現(xiàn),主要使用的技術是java的反射機制(模擬使用的是架構分為dao層,service層,controller層):

注:歡迎各位大佬的指點,小弟也在學習,說得不好多多包涵~

一.編寫dao類,用于測試:

public interface IocDao {
  public void sayhello(); //一個用來測試的接口
}

二.編寫dao的實現(xiàn)類:

public class IocDaoImpl implements IocDao {
  @Override
  public void sayhello() {
    // TODO Auto-generated method stub
    System.out.println("hello word");//實現(xiàn)我們的dao接口里的方法
  }
}

三.編寫service類:

public interface IocDaoService {
  public void sayhello();//業(yè)務類接口,這里就跟dao一樣
}

四.編寫service的實現(xiàn)類:

public class IocDaoServiceImpl implements IocDaoService {
  private IocDao iocDao;  //創(chuàng)建一個接口.
  public IocDao getIocDao() {
    return iocDao;
  }
  //編寫IocDao接口對應的set方法用于依賴注入
  //依賴注入的方式有三種:接口注入,構造方法注入,set注入;
  //此處為set注入
  public void setIocDao(IocDao iocDao) {
    this.iocDao = iocDao;
  }
  @Override
  public void sayhello() {
    // TODO Auto-generated method stub
    iocDao.sayhello();//調(diào)用接口方法
  }
}

五.編寫bean.xml配置文件.(這里的i你可以看成是IocDaoImpl類,iocService看成IocDaoServiceImpl,iocDao這是IocDaoServiceImpl里的一個屬性,這個屬性傳入的參數(shù)值為“i”);

<beans>
 <bean id="i" class="com.hck.dao.impl.IocDaoImpl"/> 
 <bean id="iocService" class="com.hck.service.impl.IocDaoServiceImpl">
   <property name="iocDao" ref="i"></property>
 </bean> 
</beans>

六.編寫工廠接口.

//模擬ClassPathXmlApplicationContext實現(xiàn)的一個接口BeanFactory
public interface BeanFactory {
  public Object getBean(String beanName);
}

七.編寫ClassPathXmlApplicationContext去讀取配置文件,并且根據(jù)bean.xml里的配置對象去生成各種bean,完成其中的注入工作.(最重要的部分Ioc的實現(xiàn)原理),一字一句都有注釋

//模擬ClassPathXmlApplicationContext去讀取配置文件
public class ClassPathXmlApplicationContext implements BeanFactory {
  //定義map集合來存放bean.xml里的bean的id跟其對應的實例化對象
  //<bean id="i" class="com.hck.dao.impl.IocDaoImpl"/> 
  //那么類似的存放bean.put("i",new IocDaoImpl());這樣子.
  Map<String, Object> beans=new HashMap<String,Object>();
  public ClassPathXmlApplicationContext(String xmlPath){
      try {
        //創(chuàng)建SAXBuilder對象解析文檔
        SAXBuilder saxBuilder = new SAXBuilder();
        //解析build里的參數(shù)是一個文件路徑.
        Document document = saxBuilder.build(xmlPath);
        //document.getRootElement().getChildren("bean")獲取所有<bean>標簽內(nèi)容
        List elements = document.getRootElement().getChildren("bean");
        //遍歷<bean>對象
        for (int i = 0; i < elements.size(); i++) {
          //獲取第一個<bean>標簽elements.get(0);
          Element element = (Element) elements.get(i);
          //獲取<bean>標簽里的<id>屬性,
          //<bean id="i" class="com.hck.dao.impl.IocDaoImpl"/> 
          //即String beanName="i";
          String beanName = element.getAttributeValue("id");
          //同上String clazz="com.hck.dao.impl.IocDaoImpl";
          String clazz = element.getAttributeValue("class");
          //加載類對象并且實例化.Object object=new IocDaoImpl();
          Object object = Class.forName(clazz).newInstance();//object是IocDaoServiceImpl
          //將他們添加在map集合里,后面可以根據(jù)beanName直接獲取到實例化對象.
          beans.put(beanName, object);
          //遍歷<bean>標簽下的<property>字標簽.
          //第一個標簽沒有字標簽所以直接跳過.已第二個為例子
          //<bean id="iocService" class="com.hck.service.impl.IocDaoServiceImpl">
          //<property name="iocDao" ref="i"></property></bean>
          List elements2 = element.getChildren("property");
          for (int j = 0; j < elements2.size(); j++) {
            //此處我們將獲得<property name="iocDao" ref="i"></property></bean>
            Element element2 = (Element) elements2.get(j);
            //相當于String propertyName="iocDao";
            String propertyName = element2.getAttributeValue("name");
            //相當于String refBean="i";
            String refBean = element2.getAttributeValue("ref");
            //相當于String propertyName="IocDao";
            //目的是為了得到一個方法的名字setIocDao,用于反射調(diào)用
            propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
            //這里的methodName="setIocDao";
            String methodName = "set" + propertyName;
            //獲取Map集合里Key="i"的值;i對應的是IocDaoImpl的實例化對象
            //相當于 Object object2 =IocDaoImpl;
            Object object2 = beans.get(refBean);
            //獲取IocDaoServiceImpl方法里的setIocDao方法.
            //第一個方法是方法名,第二個參數(shù)是方法的參數(shù)類型.
            Method method = object.getClass().getDeclaredMethod(methodName,
                object2.getClass().getInterfaces());
            //調(diào)用方法,并傳入?yún)?shù),完成依賴注入.
            method.invoke(object, object2);
          }
        }
        //      String beanName=document.getElementById(id).attributes().get("class");
        //      Object object=Class.forName(beanName).newInstance();
        //      return object;
      } catch (Exception e) {
        e.printStackTrace();
        // TODO: handle exception
      }
  }
/* (non-Javadoc)
 * @see com.hck.ioc.BeanFactory#getBean()
 */
@Override
public Object getBean(String beanName) {
  // TODO Auto-generated method stub
  return beans.get(beanName);
}  
}

八.編寫測試類

public class Ioc {
  public static void main(String[] args) {
  ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("src/bean.xml");
  IocDaoService ids=(IocDaoService)applicationContext.getBean("iocService");
  ids.sayhello();
}
}

九.顯示結果:

hello word

總結

以上就是本文關于Spring的Ioc模擬實現(xiàn)詳細介紹的全部內(nèi)容,希望對大家有所幫助。歡迎參閱:spring的IoC和DI詳解spring配置掃描多個包問題解析、SpringJDBC批量處理數(shù)據(jù)代碼示例等,有什么問題可以隨時留言,歡迎大家交流討論。

相關文章

  • SpringBoot Admin 使用指南(推薦)

    SpringBoot Admin 使用指南(推薦)

    這篇文章主要介紹了SpringBoot Admin 使用指南(推薦),Spring Boot Admin 是一個管理和監(jiān)控你的 Spring Boot 應用程序的應用程序,非常具有實用價值,需要的朋友可以參考下
    2018-01-01
  • 詳解Java如何改變字符串中的字符

    詳解Java如何改變字符串中的字符

    這篇文章主要介紹了Java如何改變字符串中的字符,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • Java?中很好用的數(shù)據(jù)結構(你絕對沒用過)

    Java?中很好用的數(shù)據(jù)結構(你絕對沒用過)

    今天跟大家介紹的就是?java.util.EnumMap,也是?java.util?包下面的一個集合類,同樣的也有對應的的?java.util.EnumSet,對java數(shù)據(jù)結構相關知識感興趣的朋友一起看看吧
    2022-05-05
  • 基于JavaMail的Java實現(xiàn)簡單郵件發(fā)送功能

    基于JavaMail的Java實現(xiàn)簡單郵件發(fā)送功能

    這篇文章主要為大家詳細介紹了基于JavaMail的Java實現(xiàn)簡單郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 詳解java中接口與抽象類的區(qū)別

    詳解java中接口與抽象類的區(qū)別

    這篇文章主要介紹了詳解java中接口與抽象類的區(qū)別的相關資料,希望通過本文能幫助到大家,讓大家輕松理解掌握接口與抽象類的區(qū)別,需要的朋友可以參考下
    2017-10-10
  • 一文徹底搞定Java中常用集合的排序方法

    一文徹底搞定Java中常用集合的排序方法

    在某些特殊的場景下我們需要在Java程序中對List集合進行排序操作,下面這篇文章主要給大家介紹了關于Java中常用集合的排序方法的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Java 實戰(zhàn)練手項目之醫(yī)院預約掛號系統(tǒng)的實現(xiàn)流程

    Java 實戰(zhàn)練手項目之醫(yī)院預約掛號系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Maven+Vue+mysql實現(xiàn)一個醫(yī)院預約掛號系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法

    Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法

    這篇文章主要介紹了Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Java+opencv3.2.0之直方圖均衡詳解

    Java+opencv3.2.0之直方圖均衡詳解

    這篇文章主要為大家詳細介紹了Java+opencv3.2.0之直方圖均衡的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Java?AQS?原理與?ReentrantLock?實現(xiàn)方法

    Java?AQS?原理與?ReentrantLock?實現(xiàn)方法

    AQS 的作用是解決同步器的實現(xiàn)問題,它將復雜的同步器實現(xiàn)分解為簡單的框架方法,開發(fā)者只需要實現(xiàn)少量特定的方法就能快速構建出可靠的同步器,這篇文章主要介紹Java AQS原理與ReentrantLock實現(xiàn),需要的朋友可以參考下
    2025-03-03

最新評論

永仁县| 竹北市| 辉县市| 荆州市| 汤阴县| 壤塘县| 蒙阴县| 旌德县| 青州市| 丰宁| 焦作市| 开阳县| 永和县| 类乌齐县| 永泰县| 休宁县| 瓦房店市| 台前县| 濮阳县| 襄城县| 突泉县| 古浪县| 宜都市| 涟源市| 集贤县| 江口县| 新乡市| 兰溪市| 聂荣县| 泰宁县| 天祝| 蒙自县| 乃东县| 吉首市| 甘泉县| 桦南县| 贵定县| 万年县| 赤峰市| 郧西县| 四会市|