第一步:首先我们应该创建一个bean.properties文件,主要通过全限定类名的方式指定(反射)唯一对象,从而直接调用这个唯一对象实现调用。
bean.properties文件
#通过全限定类型的方式指定唯一标识
#这样的话就可以直接通过全限定类名反射的方式创建一个对象,不用new出来了
accountService=com.ysw.web2.service.impl.AccountServiceImpl
accountDao=com.ysw.web2.dao.impl.AccountDaoImpl
第二步:我们应该创建一个BeanFactory工厂类用于生产我们bean.properties所反射的对象
package com.ysw.web2.bean;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
//定义一个properties对象
private static Properties properties;
//使用静态代码块为properties对象赋值
static {
try {
//只有在静态代码块中才能够new出来,实例化properties对象
properties = new Properties();
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//获取properties文件的流对象
properties.load(in);
} catch (Exception e) {
//初始化异常
throw new ExceptionInInitializerError("初始化properties失败");
}
}
/**
* 根据bean的名称获取bean对象
*
* @param beanName
* @return
*/
public static Object getBean(String beanName){
Object bean = null;
//根据beanName获取路径,通过key获取values值
String beanPath = properties.getProperty(beanName);
try {
//通过全限定类名创建一个实例对象
bean = Class.forName(beanPath).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
第三步:在创建好BeanFactory工厂类之后,就可以直接调用到代码中去了,我们就可以省略很多new的实例化操作。这里主要实现原理是通过获取唯一对象名的方式,获取全限定类名,并且通过多态的方式来把全限定类名赋值给对象。
//方法具体实现是保存在impl中的,所以我们要new出一个实现类出来
// private IAccountDao accountDao = new AccountDaoImpl();
private IAccountDao accountDao = (AccountDaoImpl)BeanFactory.getBean("accountDao");
注意:
这里的工厂模式是采用多例模式的,因为产生了多次的对象,意思就是多次使用new重新实例化对象;
如果是单例模式的话,就前前后后都使用同一个对象,至始至终都是只创建一个对象,就是只new一次。
由于多例对象创建多次,其执行效率肯定没有单例对象执行的效率高的。
BeanFactory改造为单例模式提高执行效率的方法:
package com.ysw.web2.bean;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class BeanFactory {
//定义一个properties对象
private static Properties properties;
//定义一个map容器用于存储我们要创建的对象
private static Map<String,Object> beans;
//使用静态代码块为properties对象赋值
static {
try {
//只有在静态代码块中才能够new出来,实例化properties对象
properties = new Properties();
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//获取properties文件的流对象
properties.load(in);
//实例化一个容器
beans = new HashMap<String, Object>();
//取出配置文件中所有的key,赋值给枚举对象keys
Enumeration keys = properties.keys();
//这里就相当于一次性把所有的key和value都保存到map容器中去了
while (keys.hasMoreElements()) {
//取出每一个key
String key = keys.nextElement().toString();
//根据key获取value,getProperty方法
String beanPath = properties.getProperty(key);
//通过全限定类名来实例化一个对象,反射创建对象
Object value = Class.forName(beanPath).newInstance();
//把每一个key和value存入容器
beans.put(key,value);
}
} catch (Exception e) {
//初始化异常
throw new ExceptionInInitializerError("初始化properties失败");
}
}
/**
* 通过名称获取唯一对象(单例模式)
*
* @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;
//
// //根据beanName获取路径,通过key获取values值
// String beanPath = properties.getProperty(beanName);
//
// try {
// //通过全限定类名创建一个实例对象
// bean = Class.forName(beanPath).newInstance();
// } catch (Exception e) {
// e.printStackTrace();
// }
// return bean;
// }
}