首先,获取资源属性的方式有很多种,这里先介绍两种:Abc.class.getClassLoader().getResourceAsStream(String name); 和 Abc.class.getResourceAsStream(String name); //注:Abc是普通的java类名
其次,为什么要选择使用静态代码块来获取资源呢?因为它只需要在应用被启动或者是类第一次被调用 或者是加载时仅且仅执行一次,这样带来会减少性能的消耗。 //注:静态代码块中获取当前类不能用 this关键字,同时也不能使用super关键字,试试你就知道他会报什么错啦!!
this.getClass().getClassLoader().getResource("template");
首先,调用对象的getClass()方法是获得对象当前的类类型,这部分数据存在方法区中,而后在类类型上调用getClassLoader()方法是得到当前类型的类加载器,我们知道在Java中所有的类都是通过加载器加载到虚拟机中的,而且类加载器之间存在父子关系,就是子知道父,父不知道子,这样不同的子加载的类型之间是无法访问的(虽然它们都被放在方法区中),所以在这里通过当前类的加载器来加载资源也就是保证是和类类型同一个加载器加载的。
最后调用了类加载器的getResourceAsStream()方法来加载资源。
===
===
//下面的JdbcUtils.class后面少了个()吗?应该是都可以
Properties prop = new Properties();
prop.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
String driver = prop.getProperty("driver");
Class.forName(driver);
====
- [原创]关于ClassName.class.getClassLoader的几点说明.
- 经常希望通过ClassName.class.getClassLoader().getResourceAsStream(““)来取得properties文件.通常:ClassName.class.getClassLoader().getResourceAsStream(““)取得的是WEB-INF的下级目录,比如ClassName.class.getClassLoader().getResourceAsStream(“db.properties“).在Tomcat中,可以通过增加”../”来取得上层目录,即WEB-INF目录,这样就可以把properties放在WEB-INF中统一管理。但是WLS不识别”../”。
- 另外一种土办法,就是不返回classLoader,直接ClassName.class.getResourceAsStream()。然后通过多个”../”(小于6个)来返回相应的上级目录。
- 当然,如果类扩展了HttpServlet,可以通过getServletContext().getRealPath("/")来取得Web部署目录的绝对路径。
====
因此,直接调用 this.getClass().getResourceAsStream(String name);获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream(String name); 。
====
在JDK中,getResourceAsStream是这样定义的:查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。
因为我是用txt文件当作字典,它存在一个叫dict.aspactword的包下,这样一来,编译后的文件会储存在classPath下,而不是在src下,在动态向字典添加词的时候,classPath下的txt字典没有改变,相对在getResourceAsStream的时候,拿到的自然不是最新的字典,由此感叹,在classPath下如果有不需要改变的文件,在读取时用getResourceAsStream可以保持系统良好的统一性和可移植性,但是在需要改变它们的时候,一定注意修改的路径是classPath下的文件,否则就直接用文件系统的位置来维护你所需要的文件吧
====
常见的有以下两种获取资源文件的方法:
App.class.getClassLoader().getResourceAsStream(String name)
Returns an input stream for reading the specified resource.
The search order is described in the documentation for getResource(String)
.
注:getClassLoader()默认从classpathe中找文件,name不能带“/”,否则会抛空指针
App.class.getResourceAsStream(String name):
查找资源通过给定名称,查询资源的规则与给定的类的class load来实现,这个方法由类的loader来执行,如果这个类由bootstrap加载,那么方法由ClassLoader.getSystemResourceAsStream代理执行。
代理之前,绝对的资源名称通过传入的name参数以下算法进行构造:
注:如果name以"/"开头,那么绝对路径是/后边跟的名字; 如果name不是以"/"开头,那么绝对路径是package名"."换成“/”以后再加name,例如:
com.abc.App就是/com/abc/App/name
最后,简单说说静态代码块:
格式:
class ... { static { ....... ........ ........ } }
执行时间:在这个类第一次被调用或实例化的时候就会被执行。
一般用途:静态代码块只会执行一次,一般会用来初始化一些值,并且在所有对象中全局共享。
例如:
public class DefaultClothesProperties {
public static Properties properties = new Properties();//properties属性
static {
try {
/* //方法一 :DefaultClothesProperties.class.getClassLoader().getResourceAsStream(String name) 通过类加载器加载
properties.load(DefaultClothesProperties.class.getClassLoader().getResourceAsStream("default_clothes.properties"));
System.out.println("加载配置文件"); //用以判断该静态代码块被执行几次
*/
/*//方法二 :DefaultClothesProperties.class.getResourceAsStream(String name) 通过类加载器加载
properties.load(DefaultClothesProperties.class.getResourceAsStream("/config/default_clothes.properties"));;
System.out.println("加载配置文件"); //用以判断该静态代码块被执行几次
*/
/*//方法二 :采取通过普通文件来加载配置文件方式加载 为注册用户添加默认的衣服方式
String propertiesPath = DefaultClothesProperties.class.getResource("/config/default_clothes.properties").getPath();
System.out.println("default_clothes.properties文件物理路径: " +propertiesPath);
File file = new File(propertiesPath);
FileInputStream in = new FileInputStream(file);
properties.load(in);
*/
} catch (IOException e) {
e.printStackTrace();
}
}
//通过key获取资源文件属性值
public static String getKeyOfValue(String key){
return (String)properties.get(key);
}
}