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次,他输出的结果每一次都不一样,如图所示
没调用一次,就会产生一个新的对象,这样会造成效率低下的问题
所以我们就来到第四步,看看怎么样来解决这个问题(第四步相当于引出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 = 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()获得
写在文章后:
记得第一次学spring,时间是在20天前
今天再次学起spring,突然感觉能水一篇文章,哈哈。
路过的大佬,见到我写的不好,就多多指教。
最新文章
- 《winform窗体应用程序》----------简易记事本
- 关于RPC
- Space.js – HTML 驱动的页面 3D 滚动效果
- <;a>;标签href属性与onclick事件
- WPF中利用后台代码实现窗口分栏动态改变
- Opencv2.4.4作图像旋转和缩放
- word采用尾注进行参考文献排版的一些问题
- 关于java中的==,equals()
- linux磁盘管理系列-软RAID的实现
- 基于.net core实现项目自动编译、并生成nuget包
- RLException: XXX is neither a launch file in package XXX nor is XXX a launch file name问题解决
- redis对string进行的相关操作
- 蜕变成蝶~Linux设备驱动之中断与定时器
- Java NIO -- 通道 Channel
- 纯 Java 开发 WebService 调用测试工具(wsCaller.jar)
- [LeetCode&;Python] Problem 409. Longest Palindrome
- ubuntu安装最新的mercurial
- git使用总结(包含git commit message 和 changelog 工具的介绍)
- UIO,大页内存,CPU亲和性,NUMA机制等
- 【微服务架构】SpringCloud之Ribbon
热门文章
- CSP2019心路历程
- MongoDB远程连接-命令行客户端mongo.exe
- UFUN函数 UF_CURVE函数(UF_CURVE_create_line、UF_CURVE_create_arc、UF_CURVE_ask_arc_data、UF_CURVE_ask_line_data)
- Cortex Architecture
- 使用nodegui 开发高性能的跨平台桌面端应用
- python格式化输出之format用法
- charles安装及使用
- CAP原则 (阿里)
- 图上的并行处理 Parallel Processing of Graphs
- 【Beta】设计与计划