训练目标:掌握反射代码书写,以及理解其在实际开发中的应用
需求背景:Java语言是面向对象的语言。要使用一个类,首先就需要创建类的对象,然后才可以调用类中的相关方法。但是如果每一次要使用这个类的时候都去创建一个全新的对象,那么就比较消耗内存(每new一个对象都会在堆内存中开辟新的内存空间)。因此需要考虑对这一部分的代码进行优化,优化的思想:在程序启动的时候,创建一个对象,并且将这个对象存储到一个容器中,后期要使用该类直接从容器中进行对象的获取即可。
|
| ------------------------------------------------------------ |
需求描述:在素材中reflect项目中的指定位置补全代码,使程序Entry可以正常运行。程序的运行效果如下所示:
|
|| ------------------------------------------------------------ |
实现提示:
1、ClasspathApplicationContext构造方法
① 读取classpath路径下的applicationContext.properties文件中的内容到Properties集合中
② 遍历集合通过反射创建对应类的对象存储到beans集合中
3、getBean方法:遍历beans集合获取value的Class类型和传入的Class类型进行比对,如果相等直接返回该对象
package com.test1.context;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ClasspathApplicationContext implements ApplicationContext {
// 定义一个容器存储系统中可能使用到的对象
private ConcurrentHashMap<String , Object> beans = new ConcurrentHashMap<>();
// 定义构造方法
public ClasspathApplicationContext(String fileName) {
// 补全代码
Properties properties = new Properties();
try {
//这里的目录是题目给的applicationContext.properties文件的目录
properties.load(new FileReader("junit-reflect-annotation-proxy-app\\src\\com\\test1\\applicationContext.properties"));
Set<String> keySet = properties.stringPropertyNames();
for (String key : keySet) {
String value = properties.getProperty(key);
//通过全类名获得class对象
Class c = Class.forName(value);
//通过反射创建对应类的对象
Constructor constructor = c.getDeclaredConstructor();
Object o = constructor.newInstance();
beans.put(value,o);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public <T> T getBean(Class<T> clazz) {
// 补全代码
String name = clazz.getName();
//判断传入的类是否是集合中的类
if (beans.containsKey(name)){
return (T) beans.get(name);
}else {
return null;
}
}
}