前文我们说到了创建一个bean.properties文件,然后采用Class.forName("").newInstance()的方法来创建对象,但这样创建有个弊端,就是我们每次创建出来的对象都是新的,如下:
这是bean工厂:
package com.dimples.util;
import java.util.ResourceBundle;
public class MyBeanFactory {
private static ResourceBundle bundle = null;
static {
bundle = ResourceBundle.getBundle("bean");
}
public static Object getBean(String beanName) {
try {
return Class.forName(bundle.getString(beanName)).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
这是测试方法:
public static void main(String[] args) {
for(int i = 0;i<5;i++) {
System.out.println(MyBeanFactory.getBean("CustomerService"));
}
}
结果:
但我们知道service和dao他们的功能其实跟工具类差不多,里面基本上没有类变量只有方法变量,这时也就不存在线程安全问题了,我们也没有必要创建多个实例了,如何创建单例呢?Spring中采用了恶汉式单例模式,在BeanFactory创建的时候,就将所有的bean创建好了放在一个map中:
package com.dimples.util;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
public class MyBeanFactory {
private static ResourceBundle bundle = null;
private static Map<String,Object> beanMap = new HashMap<String,Object>();
static {
bundle = ResourceBundle.getBundle("bean");
Enumeration<String> keys = bundle.getKeys();
String tempKey = null;
String beanPath = null;
Object obj = null;
while(keys.hasMoreElements()) {
tempKey = keys.nextElement();
beanPath = bundle.getString(tempKey);
try {
obj = Class.forName(beanPath).newInstance();
beanMap.put(tempKey,obj);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static Object getBean(String beanName) {
return beanMap.get(beanName);
}
}
主函数测试:
public static void main(String[] args) {
for(int i = 0;i<5;i++) {
System.out.println(MyBeanFactory.getBean("CustomerService"));
}
}
当然我们也可以自己想想怎么用懒汉式,其实也很简单,在getBean方法里写判断,如果map里有,可以直接取,如果没有,创建新的放入map并返回。