`
lucid820
  • 浏览: 38763 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

浅析类加载器的方式管理资源和配置文件

阅读更多

资源文件resource通常的加载方式,用类加载器的方式管理资源和配置文件;

示例要用到的文件:
资源文件:config.properties 里面只有一行语句:
className=java.util.ArrayList
java
代码
:
package com.itsoft;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;

public class ReflectFrame {

public static void main(String[] args) throws Exception {
    InputStream ipStream = new FileInputStream("config.properties");
    Properties props = new Properties();
    props.load(ipStream);
    ipStream.close();
    String className = props.getProperty("className");//

    Collection collection = (Collection) Class.forName(className).newInstance();
    collection.add("
框架反射
");
    collection.add("
资源文件
");
    collection.add("
类加载器
");
    System.out.println(className);//
输出:
java.util.ArrayList
    System.out.println(collection);//
输出:[框架反射, 资源文件, 类加载器
]
}
}

分析:上述代码用想运行不出错,那么config.properties必须放到工程根目录下面,此时它是一个相对路径,
但是我们发布程序时,会发现,工程根目录下面的这个配置文件是不会发布到tomcat中的,所以实际应用中,
这种做法是不可取的。

针对上述问题,有如下解决方法:
1.
使用绝对路径:如: InputStream ipStream = new FileInputStream("F:\\workspace\\webtest\\config.properties");
注:如果要应用这种绝对路径的方法,那么一定要记住用完整的路径不是硬编码,而是运算出来的。

2.使用类加载器:
原理:我们知道,每一个class文件运行的时候都必须加载到内存中,这个功能由类加载器来提供,
既然class文件它可以加载,那么其他资源文件,当然也可以由它来加载。
类加载器加载的时候,当然是从classpath的根目录路径下开始寻找并加载文件;

1)我们把config.properties文件和ReflectFrame.java放在同一目录下时:
   InputStream ipStream = ReflectFrame.class.getClassLoader().getResourceAsStream("com/itsoft/config.properties");
注意:这样用法相对于classpath,所以com/itsoft/config.properties前面不需要多余的在加一个"/";这种方式的过程就是首先
找到ReflectFrame这个类,然后通过该类找到它的加载器,再由类加载器去加载资源文件,那么我们能不能找到一个更直接的方法
又这个类去找到相关的资源文件呢?当然可以,看下面的例子,类加载器的简化形式;

2)config.properties文件和ReflectFrame.java依旧位于同一目录下:
InputStream ipStream = ReflectFrame.class.getResourceAsStream("config.properties");
注:这种做法此时用的是相对路径的形式,它是相对于class本身的;

3)config.properties位于com.itsoft.resource包下时:
InputStream ipStream = ReflectFrame.class.getResourceAsStream("resource/config.properties");
注:同2,这种做法此时用的是相对路径的形式,它是相对于class本身的;

4)config.properties位于com.itsoft.resource包下时:
InputStream ipStream = ReflectFrame.class.getResourceAsStream("/com/itsoft/resource/config.properties");
注:它也可以用绝对路径

小结:
1.
IO流的方式读写文件,通常是用绝对路径,但是为了通用性,这个绝对路径通常不要硬编码,而是运算出来的。
2.
类加载器在各种框架中普遍应用,无论是直接的加载(1),还是简化的加载(234),它们的本质都是ClassLoader
3.
简化的类加载器可以使用相对路径,也可以使用绝对路径。


代码(当资源文件位于不同的位置时的写法)
   //InputStream ipStream = new FileInputStream("F:\\workspace\\webtest\\config.properties");
   //InputStream ipStream = new FileInputStream("config.properties");
   //InputStream ipStream = ReflectFrame.class.getClassLoader().getResourceAsStream("com/itsoft/config.properties");
   //InputStream ipStream = ReflectFrame.class.getResourceAsStream("config.properties");
   //InputStream ipStream = ReflectFrame.class.getResourceAsStream("resource/config.properties");
   //InputStream ipStream = ReflectFrame.class.getResourceAsStream("/com/itsoft/resource/config.properties");

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics