文章插图
欢迎关注头条号:JAVA小野猫
首先我们要知道java获得对象的方式有四种:
1.通过new语句实例化一个对象 。
2.通过反射机制创建对象 。
3.通过clone()方法创建对象
3.通过反序列化的方式创建对象
在spring框架中,为了减低耦合,可以使用xml,properties加载配置文件,然后通过反射来获得对象,下面来讲一讲通过加载properties的配置文件来获得代理对象
第一步
创建配置文件
accountService=com.itheima.service.impl.AccountServiceImplaccountDao=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次,他输出的结果每一次都不一样,如图所示
文章插图
没调用一次,就会产生一个新的对象,这样会造成效率低下的问题
所以我们就来到第四步,看看怎么样来解决这个问题(第四步相当于引出spring容器的概念)
第四步
首先要知道为什么每次调用getBean方法都会创建一个新的对象,原因就是在于这里newInstance()
文章插图
解决方案就是,创建完对象就把他用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 = https://www.isolves.com/it/cxkf/yy/JAVA/2019-08-29/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()获得
文章插图
欢迎做Java的朋友们私信我【资料】免费获取免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,redis,Kafka,MySQL,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
推荐阅读
- 未来人工智能的趋势是什么?机器学习之父这样说
- 使用二维码的风险
- SpringBoot 深度调优,让你的项目飞起来
- 红色眼睛的孔雀鱼是什么品种 蝙蝠鱼长什么样子
- 嵌入式Linux框架的理解
- 茶是人 神 佛共同的饮品
- SpringMVC常用配置
- 茶与佛的共同诉求是心 是生命协调
- 护发素和发膜有何不同,发膜和护发素的区别是什么
- 头发油腻是什么原因?这些原因不能忽视,控制出油做好这些