当"反射"遇到"IO"触

作者: 会理发的店小二 | 来源:发表于2017-04-26 15:51 被阅读120次
    表情.jpg

    前言

    别看短,因为很精简

    会有什么基情啊?

    如果你是大神当你点进来的看的时候,你已经猜 的大概了,那就是Spring的核心机密(通过文件配置对象),为了满足一下好奇心,下文我们将一起简单的破译一下Spring的核心机密.

    那他是怎么实现的?

    下面我们将使用三步走的战略,一步一步的破译Spring的机密

    需要的材料

    名称 说明
    ObjectPool 对象向容器
    POJO 简单对象
    Config 配置文件

    实现的步骤

    1. 创建简单对象
      我们就写个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方法
        ''''''
    }
    
    1. 创建对象容器
      下面可是重头戏了,可得集中注意力了,下面将讲解大体思路:
    • 创建对象池(通过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);
      }
    
    1. 编写配置文件
      文件名称: exobj.txt
      文件内容:
    a=com.bean.Person
    b=com.bean.Person
    #分别设置a,b对象的姓名和年龄注意格式
    a%name=Zuckerberg
    a%age=30
    b%name=James
    b%age=50
    
    1. 测试结果
    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"));
      }
    }
    
    1. 输出结果
    文件里的对象:
    此人的姓名: Zuckerberg,年龄: 30岁
    此人的姓名: James,年龄: 50岁
    

    总结与优化

    下面我们在回顾一下我们的整个流程

    • 编写简单对象类和对象容器类.

    • 通过txt文件配置对象的属性.

    • 创建对象容器类的对象(好像有点绕口),并初始化.

      接下来我们怎么优化呢,无非就是从性能实用性和扩展性这两个方向:

    • 从性能实用性上考虑,我们可以采用更高效的Java io Api,和使用xml代替txt文件等,这个就是仁者见仁智了.

    • 从扩展性上考虑,那设计模式再合适不过了,我们可以采用工厂和建造者等等设计模式去实现了,这个灵活性很高,需要对设计模式有一定的了解.

    通过一步步的分析,你现在是不是感慨很多东西也不是特别的困难,那就不要停留在感慨了,赶快动起你发财的小手敲代码吧.

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

    相关文章

      网友评论

      本文标题:当"反射"遇到"IO"触

      本文链接:https://www.haomeiwen.com/subject/ydlizttx.html