<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>

          Class 和 ClassLoader 的 getResource 方法對比

          共 5256字,需瀏覽 11分鐘

           ·

          2022-01-04 14:10

          點擊上方“程序員大白”,選擇“星標(biāo)”公眾號

          重磅干貨,第一時間送達


          最近在看寫Spring的源代碼,里面有好多地方都用到了Class和ClassLoader類的getResource方法來加載資源文件。之前對這兩個類的這個方法一知半解,概念也很模糊,這邊做下整理,加深理解。

          PS:本博客主要參考了Java中如何正確地從類路徑中獲取資源,但是為了加強理解記憶自己還是將其中的重點按照自己的風(fēng)格排版記錄了下,可以點擊鏈接查看原文。

          訪問資源的主要方式

          在Java中,通??梢酝ㄟ^以下方式來訪問資源:

          • Class的getResource方法;

          • ClassLoader的getResource方法;

          • ClassLoader的getResources方法; //獲取批量資源

          • ClassLoader的getSystemResource; //靜態(tài)方法

          在使用中,Class可通過直接引用類的class屬性而獲得,或是通過實例的 getClass() 方法來獲得。獲取ClassLoader的方式則比較多,常見以下幾種:

          • 調(diào)用Class的getClassLoader方法,如:getClass().getClassLoader()

          • 由當(dāng)前線程獲取ClassLoader:Thread.currentThread().getContextClassLoader()

          • 獲取系統(tǒng)ClassLoader: ClassLoader.getSystemClassLoader()

          Class.getResource 與 ClassLoader.getResource 的區(qū)別

          public class ClassLoaderAndClassContrast {

          public static void main(String[] args) throws Exception {
          Class aClass = ClassLoaderAndClassContrast.class;
          ClassLoader classLoader = aClass.getClassLoader();

          URL resource = classLoader.getResource("cookies.properties");
          URL resource1 = aClass.getResource("dir/cookies.properties");
          if(resource!=null){
          byte[] bytes = FileCopyUtils.copyToByteArray(resource.openStream());
          System.out.println(new String(bytes));
          }
          }
          }

          兩者最大的區(qū)別,是從哪里開始尋找資源。

          • ClassLoader并不關(guān)心當(dāng)前類的包名路徑,它永遠以classpath為基點來定位資源。需要注意的是在用ClassLoader加載資源時,路徑不要以"/"開頭,所有以"/"開頭的路徑都返回null;

          • Class.getResource如果資源名是絕對路徑(以"/"開頭),那么會以classpath為基準(zhǔn)路徑去加載資源,如果不以"/"開頭,那么以這個類的Class文件所在的路徑為基準(zhǔn)路徑去加載資源。

          在實際開發(fā)過程中建議使用Class.getResource這個方法,但是如果你想獲取批量資源,那么就必須使用到ClassLoader的getResources()方法。

          public class ClassLoaderAndClassContrast {

          Class cls = ClassLoaderAndClassContrast.class;
          ClassLoader ldr = cls.getClassLoader();

          public static void println(Object s) {
          System.out.println(s);
          }

          void showResource(String name) {
          println("## Test resource for: “" + name + "” ##");
          println(String.format("ClassLoader#getResource(\"%s\")=%s", name, ldr.getResource(name)));
          println(String.format("Class#getResource(\"%s\")=%s", name, cls.getResource(name)));
          }

          public final void testForResource() throws Exception {
          showResource("");
          //對于Class來,返回這個類所在的路徑
          showResource("/");
          showResource(cls.getSimpleName() + ".class");
          String n = cls.getName().replace('.', '/') + ".class";
          showResource(n);
          showResource("/" + n);
          showResource("java/lang/Object.class");
          showResource("/java/lang/Object.class");
          }

          public static void main(String[] args) throws Exception {
          println("java.class.path: " + System.getProperty("java.class.path"));
          println("user.dir: " + System.getProperty("user.dir"));
          println("");
          ClassLoaderAndClassContrast t = new ClassLoaderAndClassContrast();
          t.testForResource();
          }
          }

          正確使用getResource方法

          • 避免使用 Class.getResource("/") 或 ClassLoader.getResource("")。你應(yīng)該傳入一個確切的資源名,然后對輸出結(jié)果作計算。比如,如果你確實想獲取當(dāng)前類是從哪個類路徑起點上執(zhí)行的,以前面提到的test.App來說,可以調(diào)用 App.class.getResource(App.class.getSimpleName() + ".class")。如果所得結(jié)果不是 jar 協(xié)議的URL,說明 class 文件沒有打包,將所得結(jié)果去除尾部的 "test/App.class",即可獲得 test.App 的類路徑的起點;如果結(jié)果是 jar 協(xié)議的 URL,去除尾部的 "!/test/App.class",和前面的 "jar:",即是 test.App 所在的 jar 文件的url。

          • 如果要定位與某個類同一個包的資源,盡量使用那個類的getResource方法并使用相對路徑。如前文所述,要獲取與 test.App.class 同一個包下的 App.js 文件,應(yīng)使用 App.class.getResource("App.js") 。當(dāng)然,事無絕對,用 ClassLoader.getResource("test/App.js") 也可以,這取決于你所面對的問題是什么。

          • 如果對ClassLoader不太了解,那就盡量使用Class的getResource方法。

          • 如果不理解或無法確定該傳給Class.getResource 方法的相對路徑,那就以類路徑的頂層包路徑為參考起點,總是傳給它以 "/" 開頭的路徑吧。

          • 不要假設(shè)你的調(diào)試環(huán)境就是最后的運行環(huán)境。你的代碼可能不打包,也可能打包,你得考慮這些情況,不要埋坑。

          獲取批量資源

          使用classLoader的getResources方法可以獲得批量資源

          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          Enumeration resources = classLoader.getResources("META-INF/MANIFEST.MF");

          Spring的ResourceLoader

          在Spring框架中ResourceLoader和ResourcePatternResolver接口封裝了獲取資源的方法,我們可以直接拿來使用。ResourceUtils這個類中提供了很多判斷資源類型的工具方法,可以直接使用。

          //前面三種的寫法效果是一樣的,必須從classpath基準(zhǔn)目錄開始寫精確的匹配路徑
          //如果想匹配多個資源,需要以classpath*/打頭,然后配合通配符使用
          ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.spring.xml");

          ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/beans.spring.xml");

          ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/beans.spring.xml");

          ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:/**/beans.spring.xml");
          • ResourceLoader 接口

          • ResourcePatternResolver 接口 --- 重點

          給出一個例子

          String txt = "";
          ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
          Resource[] resources = resolver.getResources("templates/layout/email.html");
          Resource resource = resources[0];
          //獲得文件流,因為在jar文件中,不能直接通過文件資源路徑拿到文件,但是可以在jar包中拿到文件流
          InputStream stream = resource.getInputStream();
          StringBuilder buffer = new StringBuilder();
          byte[] bytes = new byte[1024];
          try {
          for (int n; (n = stream.read(bytes)) != -1; ) {
          buffer.append(new String(bytes, 0, n));
          }
          } catch (IOException e) {
          e.printStackTrace();
          }
          txt = buffer.toString();
          • ResourceUtils

          • ResourcePatternUtils

          source:https://www.cnblogs.com/54chensongxia/p/14419509.html


          13個你一定要知道的PyTorch特性

          解讀:為什么要做特征歸一化/標(biāo)準(zhǔn)化?

          一文搞懂 PyTorch 內(nèi)部機制

          張一鳴:每個逆襲的年輕人,都具備的底層能力


          關(guān)


          ,學(xué),西學(xué)學(xué),質(zhì),結(jié)關(guān)[],學(xué)習(xí)!


          瀏覽 68
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  久久精品美女 | 免费在线看黄色片 | 国产精品久久久久久久久久久易记 | 三级在线视频观看 | 国产视频九九九 |