zoukankan      html  css  js  c++  java
  • spring框架是怎么样通过properties来获得对象的?

    首先我们要知道java获得对象的方式有四种:

    1.通过new语句实例化一个对象。

    2.通过反射机制创建对象。

    3.通过clone()方法创建对象

    3.通过反序列化的方式创建对象

    在spring框架中,为了减低耦合,可以使用xml,properties加载配置文件,然后通过反射来获得对象,下面来讲一讲通过加载properties的配置文件来获得代理对象

    第一步

    创建配置文件

    accountService=com.itheima.service.impl.AccountServiceImpl
    accountDao=com.itheima.dao.impl.AccountDaoImpl
    

    配置文件讲解:

    accountService是key,

    com.itheima.service.impl.AccountServiceImpl是value,也就是全限定类名(为什么要全限定类名,因为要通过反射来获得对象)

    第二步

    接下来就是实例化properties对象使用对象的方法load来读取配置文件了

    读取完配置文件就会获得全限定类名,有了全限定了类名创建对象就好办了

    package com.itheima.factory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    public class BeanFactory {
        private static Properties props;
        static {
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //实例化对象
            props = new Properties();
            try {
                //读取配置文件
                props.load(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static Object getBean(String beanName){
            Object bean = null;
            
            //getProperty方法 官方文档解释
            /*
            使用此属性列表中指定的键搜索属性。
            */
            String beanPath = props.getProperty(beanName);
            try {
                //获得对象
                bean = Class.forName(beanPath).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            //返回对象,谁调用我我返回给谁
            return bean;
        }
    }
    

    第三步

    改造问题

    上述的代码依然存在问题,问题如下所示

     public static void main(String[] args) {
            //IAccountService as = new AccountServiceImpl();
            for(int i=0;i<5;i++){
                IAccountService as = (IAccountService)BeanFactory.getBean("accountService");
                as.saveAccount();
                System.out.println(as);
            }
        }
    

    上述代码中,我让他循环了5次,他输出的结果每一次都不一样,如图所示

    image

    没调用一次,就会产生一个新的对象,这样会造成效率低下的问题

    所以我们就来到第四步,看看怎么样来解决这个问题(第四步相当于引出spring容器的概念)

    第四步

    首先要知道为什么每次调用getBean方法都会创建一个新的对象,原因就是在于这里newInstance()

    image

    解决方案就是,创建完对象就把他用Map存起来,所以static代码块,不仅要获得对象,还要实例化容器Map,还要添加对象到容器里面去。

    package com.itheima.factory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    public class BeanFactory {
        private static Properties props;
        private static Map<String,Object> beans;
        static {
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //实例化对象
            props = new Properties();
            try {
                //读取配置文件
                props.load(in);
                //实例化容器
                beans = new HashMap();
                //查看API文档发现
                //keys()继承自Hashtable<Object,Object>
                //使用keys()可以获取配置文件的所有键
                Enumeration keys = props.keys();
                //遍历枚举
                while(keys.hasMoreElements()){
                    String key =  keys.nextElement().toString();
                    //根据Key获取value
                    String beanPath = props.getProperty(key);
                    //反射创建对象
                    Object value = Class.forName(beanPath).newInstance();
                    //把key和value存入map集合
                    beans.put(key,value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //对象已经在初始化时就创建了,所以获取对象就没有那么麻烦了
        public static Object getBean(String beanName) {
            return beans.get(beanName);
        }
    }
    
    

    最后一步

    现在无论调用多少次getBean,对象都只有一个了,为什么只有一个,因为对象在static代码块初始化时就创建了,而且还添加到了容器中,你通过getBean方法获取就从容器中获取,而不是再次newInstance()获得

    image

    写在文章后:

    记得第一次学spring,时间是在20天前

    今天再次学起spring,突然感觉能水一篇文章,哈哈。

    路过的大佬,见到我写的不好,就多多指教。

  • 相关阅读:
    【背包九讲专题】完全背包
    【指数降幂】费马小定理降幂&欧拉降幂
    【背包九讲专题】01背包
    2016ACM-ICPC亚洲区域赛(大连)
    Codeforces Round #697 (Div. 3)题解报告(A-G)
    pywifi 网卡反复断开连接
    webdriver xpath frame alert window
    windows pexpect ssh
    python3 串口读写 pyserial
    python3 unittest addTest 与addtests
  • 原文地址:https://www.cnblogs.com/train99999/p/11328834.html
Copyright © 2011-2022 走看看