作为一个初学者,想要在这方面获得巨大的提升,必然要耐得住寂寞,和源码死磕
- 我们修改一下代码并输出观察
package cn.itycu.ui;
import cn.itycu.factory.BeanFactory;
import cn.itycu.service.IAccountService;
import cn.itycu.service.impl.AccountServiceImpl;
/**
* @author 披风少年
* @version 1.0
* @date 2020/5/23 15:21
* 模拟一个表现层,用于调用业务层
*/
public class Client {
public static void main(String[] args) {
// IAccountService accountService = new AccountServiceImpl();
for (int i = 0; i < 5; i++) {
IAccountService accountService = (IAccountService) BeanFactory.getBean("accountService");
System.out.println(accountService);
}
// accountService.saveAccount();
}
}
-----------------------------输出结果-------------------------------
"C:\Program Files (x86)\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=26505:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\15402\Desktop\demo01\target\classes" cn.itycu.ui.Client
cn.itycu.service.impl.AccountServiceImpl@a14482
cn.itycu.service.impl.AccountServiceImpl@140e19d
cn.itycu.service.impl.AccountServiceImpl@17327b6
cn.itycu.service.impl.AccountServiceImpl@14ae5a5
cn.itycu.service.impl.AccountServiceImpl@131245a
Process finished with exit code 0
我们发现对象 accountService 是多例的,每一次请求都会创建一个新的对象,执行效率肯定没有单例对象高。
我们采用map在初始化时创建对象,这样就不用反复创建对象了,修改代码如下
package cn.itycu.factory;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* @author 披风少年
* @version 1.0
* @date 2020/5/23 15:47
* 一个创建bean对象的工厂
* Bean:在计算机英语中有可重用组件的含义
* 通过工厂创建service和dao对象
*/
public class BeanFactory {
//定义一个properties对象并用static代码块儿对对象进行赋值
private static Properties props;
//定义一个map用于存放我们要创建的对象,我们称它为容器
private static Map<String, Object> beans;
static {
try {
//实例化对象,耦合只能减小不能消除,所以必要的new我们还是需要的
props = new Properties();
/**
* 获取properties文件的流对象
* 使用类加载器来获取bean.properties文本对象
* 创建在resources目录下的文件最终会成为类根目录下的文件
*/
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
//实例化容器
beans = new HashMap<String, Object>();
//取出配置文件中所有的key
Enumeration<Object> keys = props.keys();
//遍历枚举
while (keys.hasMoreElements()) {
//取出每个key
String key = keys.nextElement().toString();
//根据key获取value
String beanPath = props.getProperty(key);
//反射创建对象
Object value = Class.forName(beanPath).newInstance();
//存入容器
beans.put(key, value);
}
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化 properties 失败!");
}
}
/**
* 根据bean的名称获取单例对象
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
return beans.get(beanName);
}
/**
* 根据Bean的名词获取bean对象
* 采用泛型编程,增加工厂的复用性
* @param beanName
* @return
*/
// public static Object getBean(String beanName) {
// Object bean = null;
// try {
// String beanPath = props.getProperty(beanName);
// // newInstance 每次都会调用默认构造方法创建对象
// bean = Class.forName(beanPath).newInstance();
// } catch (Exception e) {
// e.printStackTrace();
// }
// return bean;
// }
}
-----------------------------输出结果-------------------------------
"C:\Program Files (x86)\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=27023:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\15402\Desktop\demo01\target\classes" cn.itycu.ui.Client
cn.itycu.service.impl.AccountServiceImpl@a14482
cn.itycu.service.impl.AccountServiceImpl@a14482
cn.itycu.service.impl.AccountServiceImpl@a14482
cn.itycu.service.impl.AccountServiceImpl@a14482
cn.itycu.service.impl.AccountServiceImpl@a14482
Process finished with exit code 0
我们发现输出五次都是同一个对象