前言
别看短,因为很精简
会有什么基情啊?
如果你是大神当你点进来的看的时候,你已经猜 的大概了,那就是Spring的核心机密(通过文件配置对象),为了满足一下好奇心,下文我们将一起简单的破译一下Spring的核心机密.
那他是怎么实现的?
下面我们将使用三步走的战略,一步一步的破译Spring的机密
需要的材料
名称 | 说明 |
---|---|
ObjectPool | 对象向容器 |
POJO | 简单对象 |
Config | 配置文件 |
实现的步骤
- 创建简单对象
我们就写个Person类就可以了:
public class Person {
private String name;
private String age;
public Person(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "此人的姓名: "+name+",年龄: "+age+"岁";
}
//省略get,set方法
''''''
}
- 创建对象容器
下面可是重头戏了,可得集中注意力了,下面将讲解大体思路:
- 创建对象池(通过Map集合实现)
- 将配置文件(装有对象信息)装换成输入流并获取其信息
- 根据其信息通过反射调用设置对象的值
- 最后获取对象
/**对象容器*/
public class ExtendedObjectPoolFactory {
//对象容器池
private Map objectPool = new HashMap<>();
//文件配置对象
private Properties config = new Properties();
/**
*初始化
*/
public void init(String fileName) {
try {
//将文件转换成输入流
FileInputStream fis = new FileInputStream(fileName);
{//文件配置对象加载输入流
config.load(fis);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
initPool()
}
/**
* 创建对象
*
* @param name
* @return
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
private Object createObject(String name) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//通过反射创建对象
return Class.forName(name).newInstance();
}
/**
* 初始化对象池
*/
private void initPool() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
for (String name : config.stringPropertyNames()) {
//将文件里的对象放入我们的对象池
if (!name.contains("%")) objectPool.put(name, createObject(config.getProperty(name)));
}
initProperty();
}
/**
* 初始化文件配置
*/
private void initProperty() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
for (String name : config.stringPropertyNames()) {
if (name.contains("%")) {
String [] objAndProp=name.split("%");
//获取setter方法的参数值
Object target=getObject(objAndProp[0]);
//拼接字符串toUpperCase()保证大写
String mtName="set"+objAndProp[1].substring(0,1).toUpperCase()+objAndProp[1].substring(1);
//获取实现类对应的
Class> targetClass=target.getClass();
//获取对应的方法
Method mtd=targetClass.getMethod(mtName,String.class);
//调用方法
mtd.invoke(target,config.getProperty(name));
}
}
}
/**
* 获取对象
*
* @param name
* @return
*/
public Object getObject(String name) {
return objectPool.get(name);
}
- 编写配置文件
文件名称: exobj.txt
文件内容:
a=com.bean.Person
b=com.bean.Person
#分别设置a,b对象的姓名和年龄注意格式
a%name=Zuckerberg
a%age=30
b%name=James
b%age=50
- 测试结果
public class Test {
public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchMethodException, InvocationTargetException {
ExtendedObjectPoolFactory eopf=new ExtendedObjectPoolFactory();
//初始化
eopf.init("exobj.txt");
System.out.println("文件里的对象:");
System.out.println(eopf.getObject("a"));
System.out.println(eopf.getObject("b"));
}
}
- 输出结果
文件里的对象:
此人的姓名: Zuckerberg,年龄: 30岁
此人的姓名: James,年龄: 50岁
总结与优化
下面我们在回顾一下我们的整个流程
编写简单对象类和对象容器类.
通过txt文件配置对象的属性.
-
创建对象容器类的对象(好像有点绕口),并初始化.
接下来我们怎么优化呢,无非就是从性能实用性和扩展性这两个方向:
从性能实用性上考虑,我们可以采用更高效的Java io Api,和使用xml代替txt文件等,这个就是仁者见仁智了.
从扩展性上考虑,那设计模式再合适不过了,我们可以采用工厂和建造者等等设计模式去实现了,这个灵活性很高,需要对设计模式有一定的了解.
通过一步步的分析,你现在是不是感慨很多东西也不是特别的困难,那就不要停留在感慨了,赶快动起你发财的小手敲代码吧.
另外本人对扯蛋有独到见解,欢迎前来 本人博客扯蛋,我有酒,就差你的故事了