感觉在设计模式当中,很多很多地方都要用到反射。尤其是从配置文件当中读取信息,并使用这个信息来动态加载。反射的应用特别常见,这里再一次的讨论反射和相关概念。
ClassLoader的类加载机制:
l Java当中的类不是一次性都加载到内存当中
l 而是需要的时候才动态的加载到内存当中,也就是说是运行期间的动态加载。
l 静态的语句是在加载后执行一次,而且执行一次
l Dynamic语句块每次new新的对象都会执行。
Java当中的ClassLoader很多:
Bootstrap class loader 最顶层的CL,负责管理class。可能是用c或者是汇编写的。不允许用户访问。
Extension class loader
Application class loader
Other class loaders
n Secure class loader
n URL clas loader
感觉还是在配置文件当中读取类的名字,反射最常见。
1. 属性文件的位置:
不要写死在某个目录当中
也不要用相对路径(考虑放在jar包当中的情况)
最常用的位置,放到classpath里面。就可以被properties访问到了。在eclipse当中体现为放在src目录下。Src编译好的东西,会被eclipse放到当前项目的classpath当中,所以能被properties访问了。
2. 属性文件的内容:
observers=com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog
observers为键。
com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog为值,中间用逗号隔开。
3. 使用者当中,通过一个PropertyMgr的辅助类,来得到配置文件当中的信息。
class PropertyMgr {
//使用系统对象,properties,要求配置文件放在classpath里面
privatestatic Propertiesprops =new Properties();
static {
try {
//通过properties找到配置文件
//注意这里必须使用try catch。
props.load(Test.class.getClassLoader().getResourceAsStream("com/bjsxt/dp/observer/observer.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
//通过getProperty来获取属性的值。就是在配置文件,后面的部分
publicstatic StringgetProperty(String key) {
returnprops.getProperty(key);
}
}
事实上,得到了属性的值还没有完成,得到的是一个字符串。需要继续通过string的split方法来得到每一个类。然后再生成这些类的对象们。
//对properties得到的字符串,用split来处理
String[] observers = PropertyMgr.getProperty("observers").split(",");
//对每个类,都生成对象,注意这里要try catch
for(String s : observers) {
try {
c.addWakenUpListener((WakenUpListener)(Class.forName(s).newInstance()));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}