其实所谓的框架就是通过一些配置文件来将需要运行的模块以及类、方法在软件启动的时候自动运行。如果将需要运行类以及模块配置在文件中那么便于后期的一个维护。
1. 创建一个配置文件如下
run=cn.itcast.service.UserService
me=autoRun
value=jack,lucy
2. 创建两个实现接口的服务类
UserService.java
publicclass UserService implements Service{
// 提供自动运行的方法
publicvoid autoRun(String names){
// 使用,号切割用户列表
String [] ns = names.split(",");
// 遍历
for(String name:ns){
System.out.println("姓名: "+name);
}
}
}
StartService.java
publicclass StartService implements Service {
// 提供自动运行的方法
publicvoid autoRun(String names){
// 使用,号切割用户列表
String [] ns = names.split(",");
// 遍历
for(String name:ns){
System.out.println(name);
}
}
}
以上的两个类拥有共同的方法因此可以抽取为接口
Service.java
publicinterface Service {
// 提供自动运行的方法
publicabstractvoid autoRun(String names);
}
3. 直接编写一个Main.java进行逻辑处理
public class Main {
publicstaticvoid main(String[] args) throws Exception{
// 1. 获取配置信息
Properties ps = new Properties();
// 2. 装载文件数据
ps.load(new FileInputStream(new File("jnb.ini")));
// 3. 获取数据
String str_clazz = ps.getProperty("run");
String str_method = ps.getProperty("me");
String str_value = ps.getProperty("value");
// 4. 反射获取Class对象
Class clazz = Class.forName(str_clazz);
// 5. 创建对象
Constructor con = clazz.getConstructor(null);
Service service = (Service)con.newInstance(null);
// 6. 调用相关的方法
Method method = clazz.getMethod(str_method, String.class);
method.invoke(service, str_value);
}
}
这样的话就基本的实现了一个框架的模拟,大家以后就可以同配置文件的形式修改程序运行的服务类了。
JavaSE中的路径问题
举例1:读取项目根目录下的数据。
privatestaticvoid readRoot() throws FileNotFoundException,IOException {
BufferedReader br = new BufferedReader(new FileReader(
new File("jnb.txt")));
String line = br.readLine();
System.out.println(line);
}
举例2:读取和class文件同目录的资源数据。
privatestaticvoid readClassPath() throws FileNotFoundException,
IOException {
URL url= SoreceReader.class.getResource("jnb.txt");
String path = url.getPath();
System.out.println(path);
BufferedReader br = new BufferedReader(
new FileReader(new File(path)));
String line = br.readLine();
System.out.println(line);
}
举例3:读取在src目录的资源数据。
privatestaticvoid readBin() throws FileNotFoundException,IOException {
URL url= SoreceReader.class.getResource("../../../jnb.txt");
String path = url.getPath();
System.out.println(path);
BufferedReader br = new BufferedReader(
new FileReader(new File(path)));
String line = br.readLine();
System.out.println(line);
}
可以直接返回一个指定资源的输入流对象。
publicstaticvoid main(String[] args) throws Exception{
InputStream in = SoreceReader.class.getResourceAsStream("../../../jnb.txt");
BufferedReader br = new BufferedReader(
new InputStreamReader(in));
String line = br.readLine();
System.out.println(line);
}
getResourceAsStreamVS getResource
getResourceAsStream直接返回了流对象因此无法获取资源的信息。
getResource直接返回的是资源的绝对路径,那么封装File可以快速的获取资源的信息。所有在文件下载的时候一般使用该方法。
学生疑惑解答
1. 直接导入我的项目直接报错?
使用自己的JRE环境即可。
2. 使用枚举为什么不能直接创建对象,哪怕直接在静态代码块中调用构造函数?
直接使用静态代码块初始化好的枚举值即可。
3. 使用反射技术实现静态函数的反射以及调用。
总结
大家主要要掌握以下几点内容:
增强for循环,而且必须要清楚底层采用的是迭代器进行的迭代。
安全的枚举,全部要会。枚举是单例的,有时在项目中如果要使用单例,那么可以使用枚举。
泛型的应用。
了解反射以及框架的实现原理。
熟练掌握BeanUtils工具以及学习开源工具的方式。
熟练掌握在JavaSE中获取不同资源的方式。
练习
1. 使用Properties类读取配置文件中的属性值。
2. 使用Properties配置一个以下的值:
class=java.lang.String
使用程序获取指定类的Class对象进行属性对象的反射。
3. 使用反射技术将原始的单例模式进行反射实例。 // false
4. 使用反射技术看是否可以将枚举的单例反射出来实例。 // 报错
使用Class对象的方法获取任意项目位置的资源文件数据。