整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          package-info.java文件詳解

          package-info.java文件詳解

          、pacakge-info.java介紹

          pacakge-info.java是一個(gè)Java文件,可以添加到任何的Java源碼包中。pacakge-info.java的目標(biāo)是提供一個(gè)包級(jí)的文檔說明或者是包級(jí)的注釋。

          pacakge-info.java文件中,唯一要求包含的內(nèi)容是包的聲明語句,比如:

          package com.ch.service;

          二、包文檔

          在Java 5之前,包級(jí)的文檔是package.html,是通過JavaDoc生成的。而在Java 5以上版本,包的描述以及相關(guān)的文檔都可以寫入pacakge-info.java文件,它也用于JavaDoc的生成。比如:

          /**
          * dev1.ch包描述<br>
          * 基于Apache DbUtils庫封裝的工具庫,簡化開發(fā)
          * @author Li Qiang<br>
          * date: 2015.5.13
          * @since 1.7
          * @version 1.0
          *
          */
          package dev1.ch;
          

          上面的說明通過JavaDoc生成如下:

          這里寫圖片描述

          點(diǎn)擊dev1.ch程序包的鏈接后顯示:

          這里寫圖片描述

          三、包注釋

          注釋對于程序員來說非常重要,pacakge-info.java文件包含了包級(jí)的注釋。我們還可以使用ElementType來自定義注釋。

          包注釋當(dāng)然是ElementType.PACKAGE了,除此之外,還有:

          • ElementType.TYPE (class, interface, enum)
          • ElementType.FIELD (instance variable)
          • ElementType.METHOD ElementType.PARAMETER
          • ElementType.CONSTRUCTOR
          • ElementType.LOCAL_VARIABLE
          • ElementType.ANNOTATION_TYPE (應(yīng)用于另一個(gè)注解上)

          比如,想讓包中的所有類型過時(shí)(Deprecate),你可以注釋每一個(gè)單獨(dú)的類型(類、接口、枚舉等),如下所示:

          @DEPRECATED
          PUBLIC CLASS CONTACT {
          }
          

          或者是可以在package-info.java包聲明文件中使用@Deprecated注釋,它可以讓包中的一切均過時(shí)。

          @Deprecated

          package dev1.ch.domain;

          四、把package-info.java添加到包中

          可以手動(dòng)在包目錄下創(chuàng)建package-info.java文件,也可以通過Eclipse工具實(shí)現(xiàn)這一點(diǎn)。

          寫在最后:

          碼字不易看到最后了,那就點(diǎn)個(gè)關(guān)注唄,只收藏不點(diǎn)關(guān)注的都是在耍流氓!

          關(guān)注并私信我“架構(gòu)”,免費(fèi)送一套Java架構(gòu)資料,先到先得!

          馨提示:這是一篇私有的package客戶端查詢的平臺(tái)搭建文章,牽扯到python中的Django框架,雖和Flutter相關(guān),但客戶端的代碼并沒有關(guān)聯(lián),請您根據(jù)需要進(jìn)行閱讀。

          公有的package,對于一個(gè)Flutter開發(fā)者而言,再熟悉不過,比如常見的網(wǎng)絡(luò)庫dio,存儲(chǔ)庫shared_preferences等等,我們都可以在官網(wǎng)進(jìn)行查找和使用,中文地址:https://flutter.cn/,很方便的就可以找到package網(wǎng)址,如下圖所示:

          點(diǎn)擊打開之后,如下圖,我們就可以查找想要的三方庫。

          在一些特定的環(huán)境下,自己公司封裝的庫,不適合于發(fā)布到公有的倉庫中,那么就需要搭建一套私有的倉庫,和Android中的私有Maven是一個(gè)道理,私有的服務(wù)端倉庫,搭建起來很是簡單,因?yàn)楣俜揭呀?jīng)給我們提供了,地址是:https://github.com/dart-archive/pub_server,我們只需要按照流程,就可以完美的實(shí)現(xiàn),在這里就不過多介紹,本篇重在于解決如何查看,也就是客戶端查看,而不是上傳,請各位老鐵須知。

          私有的package存儲(chǔ)服務(wù)搭建好之后,一般來說就足夠了,只需要把使用方式整理成一個(gè)文檔即可,但是,如果上傳的package足夠多,而且公司的開發(fā)人員又足夠多,那么開發(fā)一個(gè)針對性的查看平臺(tái)類似于官網(wǎng)提供的查看就很有必要了。

          目前客戶端查看實(shí)現(xiàn)的方案,有官網(wǎng)提供,當(dāng)然也有一些三方提供,大家可以根據(jù)自己公司需求進(jìn)行選擇性使用,這里采用的是自己從0到1開發(fā),旨在一個(gè)簡單易用。


          本篇的內(nèi)容大概如下:


          1、最終的實(shí)現(xiàn)效果一覽

          2、采用哪種語言作為接口開發(fā)

          3、前端UI設(shè)計(jì)以及搭建

          4、如何獲取package對應(yīng)的相關(guān)信息

          5、路由設(shè)置和頁面返回

          6、相關(guān)總結(jié)


          一、最終的實(shí)現(xiàn)效果一覽

          UI效果主打簡潔,和官網(wǎng)的風(fēng)格,簡單的保持一致,內(nèi)容區(qū)域只展示基本的內(nèi)容,別的什么也不展示,以動(dòng)畫的形式,展示左右結(jié)構(gòu),只有簡單的檢索和列表展示及簡單的內(nèi)容展示。

          首頁


          搜索頁面



          內(nèi)容展示頁面

          右側(cè)為測試內(nèi)容,點(diǎn)擊想要的Item后,以動(dòng)畫的形式滑入。


          二、采用哪種語言作為接口開發(fā)

          既然作為一個(gè)客戶端查看,難免需要一個(gè)服務(wù)端作為支持,不然內(nèi)容從哪來?服務(wù)端主要負(fù)責(zé)提供package檢索和內(nèi)容的返回,客戶端負(fù)責(zé)內(nèi)容展示,基于這是一個(gè)比較小得項(xiàng)目,選擇一個(gè)輕量級(jí)的語言比較好,一開始選的是php,奈何最近一段時(shí)間對python比較感興趣,于是就選擇使用python作為服務(wù)端語言,使用的是比較成熟的Django框架。

          關(guān)于Django框架,這里不做過多介紹,后續(xù)準(zhǔn)備了相關(guān)文章進(jìn)行著重的概述,所以啊鐵子們,需要注意,雖是開發(fā)的Flutter的私有package查看,但是呢,用的是python,這個(gè)大家一定要熟知。

          三、前端UI設(shè)計(jì)以及搭建

          關(guān)于前端的UI,確實(shí)沒什么好設(shè)計(jì)的,都是遵循著極簡的模式,能多簡單就多簡單,一共三個(gè)頁面,都是html文件,第一個(gè)是首頁,第二個(gè)是搜索和內(nèi)容展示頁,第三個(gè)是上傳package介紹頁。這里著重介紹下搜索和內(nèi)容展示頁面。

          搜索和內(nèi)容展示頁面,搜索的時(shí)候是以列表的形式展示,點(diǎn)擊相關(guān)Item后,左邊展示列表,右邊展示內(nèi)容,有一個(gè)動(dòng)態(tài)切換的效果,這里簡單的做了一個(gè)小動(dòng)畫。

            $(".list_name").each(function () {
                          $(this).click(function () {
                              //點(diǎn)擊之后查看詳情
                              $(".list_div").animate({marginLeft: "5%", width: "40%"});
                              setTimeout(function () {
                                  $(".list_content").css("display", "block");
                                  $(".list_content").animate({right: "5%"});
                              }, 300);
                              //請求接口信息
                              $.get("../queryReadMe?fileName=gwm_lib", function (data) {
                                  let content=data.data;
          
                                  var converter=new showdown.Converter();
                                  var html=converter.makeHtml(content);
                                  $(".list_text").html(html);
                              });
                          });
                      });


          為了支持md文件加載,這里使用了一個(gè)第三方showdown.min.js,當(dāng)然了在實(shí)際的開發(fā)中,大家可以隨意。


          關(guān)于填充內(nèi)容,使用的是Django的模板,主要用于分離文檔的表現(xiàn)形式和內(nèi)容,和Vue使用起來很像。


          <div class="pub_div">
              <div class="pub_input_div">
                  <input class="pub_input" placeholder="Search packages"/>
                  <img src="../static/img/pub_search.png" class="pub_search"/>
              </div>
              <!--搜索結(jié)果頁-->
              <div class="list_div">
                  {% if count > 0 %}
                      {% for search in searchList %}
                          <div class="list_item">
                              <div class="list_name">{{ search.name }}</div>
                              <div class="list_author">
                                  最新版本:<span style="font-style: italic;color: #7a8dc5;">{{ search.version }}</span>
                                  作者:{{ search.author }}
                              </div>
                              <div class="list_description">{{ search.description }}</div>
                              <div class="list_time">
                                  {{ search.time }}
                              </div>
                          </div>
                      {% endfor %}
                  {% else %}
                      <div class="list_no">暫時(shí)沒有數(shù)據(jù)</div>
                  {% endif %}
              </div>
              <!--使用詳情-->
              <div class="list_content">
                  <div class="list_text">
          
                  </div>
              </div>
          </div>


          四、如何獲取package對應(yīng)的相關(guān)信息

          當(dāng)服務(wù)端搭建完成之后,便可以按照相關(guān)流程,上傳自己的package,無論誰去上傳,最終都會(huì)存到一個(gè)路徑下,比如,我做為測試用的,所有的package都上傳到了E盤下的tmp目錄下的package-db。

          在package-db目錄下,存放的就是所有上傳到私服的package,目前做為測試,僅上傳了一個(gè),我們繼續(xù)打開:

          每個(gè)package下存放的就是各個(gè)對應(yīng)的版本號(hào),再往下,就是存放的資源了。


          知道了上傳的基本目錄結(jié)構(gòu)后,一個(gè)問題就來了,如何拿到package的相關(guān)信息呢?比如名字,時(shí)間,版本號(hào),作者,如何使用等?

          其實(shí)大家,可以發(fā)現(xiàn),在每個(gè)版本號(hào)的里面都有一個(gè)yaml文件,而這個(gè)yaml文件里就是我們上傳到package時(shí)所填的一些信息,如下所示:

          我們只需要逐行讀取信息就可以拿到了,拿到信息之后,我們就可以用一個(gè)數(shù)組存儲(chǔ)起來,組成我們需要的列表了。

          只提供package而不提供如何使用,顯然是不科學(xué)的,形同雞肋,會(huì)讓人懵逼,最終會(huì)造成,你這個(gè)package怎么使用?方法怎么調(diào)?屬性怎么使用?沒有一個(gè)簡單的使用說明,會(huì)讓人望而卻步。

          但是,使用方式如何獲取呢?當(dāng)我們開源一個(gè)庫,為了讓別人了解如何使用,一般都會(huì)在哪里書寫呢?README啊,是不是,隨便去github上扒拉一個(gè)不錯(cuò)的開源,相信都會(huì)有一個(gè)README文件,同樣的,我們再上傳package時(shí),盡量也書寫一下README文件,在README里書寫相關(guān)使用方式或步驟即可,有了README文件,在上傳的時(shí)候就會(huì)跟著一起上傳,如下圖,它是在tar.gz壓縮包里:



          壓縮文件目錄:



          打開README文件,是不是發(fā)現(xiàn)和上邊的截圖內(nèi)容展示一樣,沒錯(cuò),所謂的package使用方式,就是通過讀取壓縮文件里的README內(nèi)容而來的。




          通過以上的分析,我們便可以拿到我們想要的內(nèi)容,如,名字,版本號(hào),描述,作者,上傳時(shí)間,使用方式等等,具體的代碼如下:


          # Flutter私有庫查詢列表頁面
          def package(request):
              key=request.GET.get("key")
              packagePath="E:\\tmp\\package-db"
              rootPath=os.listdir(packagePath)
              # 遍歷,查找一樣的
              endList=[]
              for path in rootPath:
                  if path.find(key) !=-1:
                      # 繼續(xù)尋找,找到最大的一個(gè)版本號(hào)
                      versionPath=packagePath + "\\" + path
                      versionList=os.listdir(versionPath)
                      # 找出最大的一個(gè)版本號(hào)
                      versionDir=versionList[len(versionList) - 1]
                      # 遍歷Yaml文件后,讀取內(nèi)容
                      versionYamlPath=versionPath + "\\" + versionDir + "\\pubspec.yaml"
                      # 讀取內(nèi)容
                      file=open(versionYamlPath, "r", encoding="UTF-8")
                      lines=file.readlines()  # 讀取所有的行數(shù)
                      name=lines[0].replace("\n", "").replace("name: ", "")  # 名字
                      description=lines[1].replace("\n", "").replace("description: ", "")  # 描述信息
                      version=lines[2].replace("\n", "").replace("version: ", "")  # 版本號(hào)
                      author=lines[3].replace("\n", "").replace("author: ", "")  # 作者
                      c_time=os.path.getctime(versionYamlPath)
                      e_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(c_time))
                      json={"name": name, "version": version, "description": description, "author": author, "time": e_time}
                      endList.append(json)
              cou=len(endList)
              return render(request, "flutter/pubList.html", {"searchList": endList, "count": cou})



          五、路由設(shè)置和頁面返回


          每個(gè)Django框架都有一個(gè)對應(yīng)的urls文件,也就是路由文件,在這個(gè)文件里,我們可以設(shè)置我們跳轉(zhuǎn)的頁面,請求的接口等信息。

          path('flutter/pub', index.pub),  # Flutter私有庫查詢首頁面
          path('flutter/package', index.package),  # Flutter私有庫查詢列表頁面
          path('flutter/packageUpload', index.packageUpload),  # Flutter私有庫如何上傳頁面


          路由指向的頁面配置


          # Flutter私有庫查詢首頁面
          def pub(request):
              return render(request, "flutter/pub.html")
          
          
          # Flutter私有庫如何上傳頁面
          def packageUpload(request):
              return render(request, "flutter/pubUpload.html")

          六、相關(guān)總結(jié)

          基于Django框架,就簡單的實(shí)現(xiàn)了一個(gè)客戶端的package查詢頁面,前邊也說過,不一定非得要使用python來作為服務(wù)端,使用php或者Java又或者其他語言都是可行的,最主要的就是選擇一個(gè)自己熟悉的語言,這樣寫起來才比較順手。

          還有需要注意的是,如果官網(wǎng)和一些三方提供的package查詢,能夠滿足我們的需求,我們也可以直接使用,沒有必要再從0到1進(jìn)行開發(fā)。

          按照往常的文章風(fēng)格,最后我都會(huì)貼出來源碼或者開源地址,但是呢,實(shí)在是過于簡單,如果大家了解了Django后,就會(huì)發(fā)現(xiàn)這些都是基本的知識(shí)點(diǎn),所以就不貼了,但是主要的代碼,都在文中介紹了。

          ackage-info.java 介紹

          pacakge-info.java 是一個(gè) Java 文件,目標(biāo)是提供一個(gè)包級(jí)的文檔說明及包級(jí)的注釋。在 Java 5 之前,包級(jí)的文檔是 package.html,是通過 JavaDoc 生成的。而在 Java 5 之后版本,包的描述以及相關(guān)的文檔都可以寫入 pacakge-info.java 文件。

          創(chuàng)建 package-info.java

          pacakge-info.java 不能隨便被創(chuàng)建,會(huì)報(bào) This is not a valid Java qualified name 錯(cuò)誤,類名無效,因?yàn)轭惷荒馨?-,那么怎么創(chuàng)建這個(gè)文件呢?

          創(chuàng)建一個(gè)普通的文件,文件名設(shè)置為 package-info.java 即可,或者從其它項(xiàng)目中復(fù)制一個(gè)。

          pacakge-info.java 只需要聲明 package

          package com.test;

          package-info.java 用途

          提供包級(jí)別的注釋

          package-info.java 添加注釋

          /**
           * 測試 package-info 的包注釋功能
           * 
           * @author mimi
           * @since 1.0.0-RELEASE
           * @version 2.0.0-RELEASE
           */
          package com.test;

          執(zhí)行 javadoc 之后查看效果圖

          • 如何在 idea 中執(zhí)行 javadoc

          Tools -> Generate JavaDoc,選擇 Output directory,在 Othre Command line arguments 中填入 -encoding utf-8 -charset UTF-8,用于解決中文亂碼問題

          提供包級(jí)別的注解

          自定義一個(gè)注解

          @Target(ElementType.PACKAGE)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface PackageAnnotation {
          }

          在 package-info.java 上添加注解,注解加在 package 之上,注解的地方與平常用的注解稍有不同

          @PackageAnnotation
          package com.test;

          獲取包注解

          public class Test {
              public static void main(String[] args) {
                  System.out.println("Package Annotation:");
                  Arrays.stream(Test.class.getPackage().getAnnotations())
                          .forEach(System.out::println);
                  System.out.println();
                  System.out.println("Class Annotation:");
                  Arrays.stream(Test.class.getAnnotations())
                          .forEach(System.out::println);
              }
          }

          輸入結(jié)果如下,通過包可以獲取到包的注解。

          Package Annotation:
          @com.test.PackageAnnotation()

          Class Annotation:


          @Deprecated 的使用

          @Deprecated 可以作用在一個(gè)類,一個(gè)方法或者一個(gè)變量上,意味著被標(biāo)記的元素是過時(shí)的,在之后的版本可能不再支持,不建議使用。但如果是一整個(gè)功能下線,@Deprecated 也可以作用在包上,將整個(gè)包標(biāo)記為過時(shí)。

          @Deprecated
          package com.test;

          提供包級(jí)別的變量

          package-info.java 中只能聲明 default 默認(rèn)訪問權(quán)限的類,只能包內(nèi)訪問,其它包包括子包都不可訪問。

          package com.test;
          class Constant {
              static final String PACKAGE_NAME="Test";
          }

          同一個(gè)包下使用


          主站蜘蛛池模板: 中文字幕日韩人妻不卡一区 | 亚洲av无码天堂一区二区三区 | 亚洲中文字幕乱码一区| 日本成人一区二区三区| 久久久久人妻一区精品| 亚洲一区二区三区高清| 性色av无码免费一区二区三区| 国产伦精品一区二区三区不卡| 日本一区免费电影| 精品一区二区三区四区电影| 久久精品无码一区二区日韩AV| 无码精品一区二区三区免费视频| 无码国产精品一区二区免费式直播 | 国产精品高清一区二区三区不卡 | 久久精品一区二区影院| 国产免费无码一区二区| 亚洲国产成人久久一区二区三区| 精品一区二区三区视频| 综合人妻久久一区二区精品| 五十路熟女人妻一区二区| 视频在线一区二区| 少妇激情一区二区三区视频| 国产麻豆剧果冻传媒一区| 国产午夜精品一区二区三区漫画| 亚洲av日韩综合一区久热| 国产福利电影一区二区三区久久老子无码午夜伦不 | 成人在线视频一区| 奇米精品视频一区二区三区| 日韩三级一区二区三区| 亚洲av福利无码无一区二区| 国产视频福利一区| 精品三级AV无码一区| 免费人人潮人人爽一区二区| 久久综合亚洲色一区二区三区 | 久久精品国产一区二区三区日韩| 精品国产一区二区麻豆| 国产爆乳无码一区二区麻豆 | 一区二区在线视频| 99精品高清视频一区二区| 女同一区二区在线观看| 久久国产精品亚洲一区二区|