<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          《跟二師兄學(xué)Nacos吧》EXT-03篇 Nacos中此處為什么采用反射機(jī)制?

          共 3886字,需瀏覽 8分鐘

           ·

          2021-07-27 11:43

          學(xué)習(xí)不用那么功利,二師兄帶你從更高維度輕松閱讀源碼~

          大家可能看到過很多寫Java反射機(jī)制的文章,但如果在閱讀源碼的過程中,遇到反射機(jī)制的使用,你是否想過為什么要這么用嗎?

          這篇文章就帶大家來看看Nacos中對(duì)Java反射機(jī)制的一處實(shí)踐案例。這篇文章既屬于知識(shí)點(diǎn)的分析,也屬于Nacos設(shè)計(jì)層面的分析。

          Nacos中反射機(jī)制實(shí)踐

          先來介紹一下Nacos反射機(jī)制使用的背景。

          nacos-client項(xiàng)目中,可以通過NacosFactory獲得NamingService,然后基于NamingService來進(jìn)行服務(wù)實(shí)例的注冊(cè)功能:

          NamingService namingService = NacosFactory.createNamingService(properties);
          namingService.registerInstance("nacos.test.1", instance);

          而在NacosFactory中又是基于NamingFactory來實(shí)現(xiàn)NamingService的創(chuàng)建的:

          public static NamingService createNamingService(Properties properties) throws NacosException {
              return NamingFactory.createNamingService(properties);
          }

          NamingFactory具體創(chuàng)建部分代碼如下:

          public static NamingService createNamingService(Properties properties) throws NacosException {
              try {
                  Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
                  Constructor constructor = driverImplClass.getConstructor(Properties.class);
                  return (NamingService) constructor.newInstance(properties);
              } catch (Throwable e) {
                  throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
              }
          }

          到這里,終于看到了反射機(jī)制的使用了,通過Class#forName方法獲取Class對(duì)象,然后獲取構(gòu)造方法,創(chuàng)建實(shí)例。

          如果你閱讀源碼時(shí)只看到這些,可能你會(huì)錯(cuò)過一些有意思的設(shè)計(jì)和事情。你是否思考過,為什么這里要采用反射機(jī)制呢?直接new一個(gè)對(duì)象不行嗎?

          在解答上述問題之前,我們先來簡(jiǎn)單科普一下Java發(fā)反射機(jī)制。

          Java反射機(jī)制

          這里從基本概念、原理、簡(jiǎn)單實(shí)踐說起。

          Java反射簡(jiǎn)介

          Java是預(yù)編的語(yǔ)言,對(duì)象的類型在編譯期已經(jīng)確定。在程序運(yùn)行時(shí)可能需要?jiǎng)討B(tài)加載某些類,這些類之前用不到,所以就沒有被加載到JVM中。需要時(shí),可通過反射在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建對(duì)象并調(diào)用其屬性或方法,而不需要在編譯期就知道運(yùn)行的對(duì)象是誰(shuí)。

          Java反射機(jī)制的核心是在程序運(yùn)行時(shí)動(dòng)態(tài)加載類并獲取類的詳細(xì)信息,從而能夠操作類或?qū)ο蟮膶傩院头椒ā?/p>

          Java反射的優(yōu)缺點(diǎn)

          Java反射的優(yōu)點(diǎn):

          • 增加程序的靈活性,避免將程序?qū)懰赖酱a里;
          • 代碼簡(jiǎn)潔,提高代碼的復(fù)用率,外部調(diào)用方便;
          • 對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;

          反射的原理

          在了解反射的基本原理之前,我們需要知道在Java程序編譯完成之后,會(huì)把所有class文件中所包含的類的基本元信息裝載到JVM內(nèi)存中,以Class類的形式保存。Class類可理解為描述類的類,每一個(gè)Class類對(duì)象代表一個(gè)具體類的基本元信息。反射就是在Class類的基礎(chǔ)上進(jìn)行的,Class類對(duì)象存儲(chǔ)著類的所有相關(guān)信息。

          反射原理

          關(guān)于JVM內(nèi)部的操作步驟,我們這里不做拓展。需要了解的就是Class對(duì)象是JVM加載.class文件之后生成的對(duì)象,而反射機(jī)制提供了獲取該對(duì)象,可以基于此進(jìn)行屬性訪問或?qū)ο髽?gòu)造。而這一步是發(fā)生在運(yùn)行時(shí)期間。

          反射的基本使用

          通常使用反射有三種方式:

          // 方式一:使用Class.forName靜態(tài)方法
          Class clz = Class.forName("java.lang.String");

          // 方式二:使用.class方法
          Class clz = String.class;

          // 方式三:使用類對(duì)象的getClass()方法

          String str = new String("Hello");
          Class clz = str.getClass();

          上述三種方式,一般常用第一種,字符串參數(shù)可以傳入也可以寫在配置文件中。第二種需要導(dǎo)入類包,依賴太強(qiáng),不導(dǎo)包就拋編譯錯(cuò)誤。第三種對(duì)象都有了還要反射干什么。

          所以說,通常我們學(xué)習(xí)的時(shí)候,知道了很多種方式,而真正使用時(shí),還是需要根據(jù)場(chǎng)景進(jìn)行選擇。而Nacos的源碼中就采用了第一種的方式。

          關(guān)于反射的其他API的使用此處就不再展開了,下面回到主題,來思考一下Nacos為什么使用反射,同時(shí)為什么采用第一種方式。

          Nacos反射機(jī)制原理分析

          在分析之前,我們先來看一下項(xiàng)目結(jié)構(gòu)。首先,nacos-client項(xiàng)目依賴于nacos-aip項(xiàng)目,NamingFactory和NamingService位于nacos-api項(xiàng)目當(dāng)中。而具體被實(shí)例化的對(duì)象類com.alibaba.nacos.client.naming.NacosNamingService,很明顯位于nacos-client當(dāng)中。

          反射原理

          通過上圖我們可以看到,NamingFactory中實(shí)現(xiàn)了NamingService的實(shí)例化業(yè)務(wù)邏輯,但此時(shí)nacos-api項(xiàng)目并沒有NacoNamingService,也就無法采用上面提到的其他兩種方法,只能通過Class.forName方式來進(jìn)行實(shí)現(xiàn)了。

          其實(shí)這里的設(shè)計(jì)與數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類似,nacos-api中通過NamingService定義了一個(gè)接口,也就是定義了一個(gè)標(biāo)準(zhǔn)。而nacos-client中實(shí)現(xiàn)了這個(gè)標(biāo)準(zhǔn),并且還要滿足兩個(gè)條件:第一,該實(shí)現(xiàn)類實(shí)現(xiàn)自NamingService;第二,該類的全路徑名要與NamingFactory中的實(shí)例化對(duì)象時(shí)的名稱一樣。

          回頭再仔細(xì)想象,Nacos的用法,也不正是反射機(jī)制很典型的使用場(chǎng)景之一嗎?

          小結(jié)

          本文從Nacos的反射機(jī)制出發(fā),深入思考提出問題,并簡(jiǎn)單介紹了Java的反射機(jī)制。最終進(jìn)一步分析Nacos項(xiàng)目結(jié)構(gòu),解答了最開始的疑問。你會(huì)如此閱讀源代碼嗎?你學(xué)到了嗎?趕緊關(guān)注上車!后續(xù)更多干貨輸出。

          如果文章內(nèi)容有問題或想技術(shù)討論請(qǐng)聯(lián)系我(微信:zhuan2quan,備注Nacos),如果覺得寫的還不錯(cuò),值得一起學(xué)習(xí),那就關(guān)注一下吧。

          往期推薦

          《跟二師兄學(xué)Nacos吧》EXT-02篇 面試官問工廠模式,你理解的對(duì)嗎?

          《跟二師兄學(xué)Nacos吧》EXT-01篇 看看Nacos是怎么活學(xué)活用簡(jiǎn)單工廠模式的!

          《跟二師兄學(xué)Nacos吧》第1篇 Nacos客戶端服務(wù)注冊(cè)源碼分析

          Spring Boot Actuator的端點(diǎn)都怎么用?咱用事實(shí)說話!

          Spring Boot Actuator集成,難的是靈活運(yùn)用!

          “精通”,不是為了面試,而是為了個(gè)人品牌



          如果你覺得這篇文章不錯(cuò),那么,下篇通常會(huì)更好。添加微信好友,可備注“加群”(微信號(hào):zhuan2quan)。

          一篇文章就看透技術(shù)本質(zhì)的人,
            和花一輩子都看不清的人,
            注定是截然不同的搬磚生涯。
          ▲ 長(zhǎng)按關(guān)注”程序新視界“,洞察技術(shù)內(nèi)幕
          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  3级片在线| 欧美精品三级视频在线看 | 阿v视频在线观看 | 亚洲无 码A片在线观看 | 青娱乐极品精品 |