
表情.jpg
前言
别看短,因为很精简
会有什么基情啊?
如果你是大神当你点进来的看的时候,你已经猜 的大概了,那就是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<String, Object> 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文件等,这个就是仁者见仁智了.
- 从扩展性上考虑,那设计模式再合适不过了,我们可以采用工厂和建造者等等设计模式去实现了,这个灵活性很高,需要对设计模式有一定的了解.
通过一步步的分析,你现在是不是感慨很多东西也不是特别的困难,那就不要停留在感慨了,赶快动起你发财的小手敲代码吧.

表情.jpg
另外本人对扯蛋有独到见解,欢迎前来本人博客扯蛋,我有酒,就差你的故事了