利用Bean工厂模式降低程序间的依赖
- Bean,再计算机英语中,有可重用组件的含义
- JavaBean:用Java语言编写的可重用组件
- 我们通常认为Javabean=实体类,实际上Javabean > 实体类
- 它就是创建我们的service和dao对象的
- 第一个:需要一个配置文件来配置我们的servic和dao
- 配置的内容:唯一标识 = 全限定类名(key = value)
- 第二个:通过读取配置文件中配置的内容,反射创建对象
- 我的配置文件可以是xml也可以是properties
模拟保存账户的操作
- 创建账户业务层接口和业务层实现类
- 创建账户持久层接口和持久层实现类
- 创建一个表现层的类,用于调用业务类
- 创建配置文件Bean.properties
在配置文件中指定业务层实现类和持久层实现类的全限定类名
- 创建Bean工厂类来读取配置文件信息
目录结构:
读取配置文件信息
- 定义一个Properrties对象
- 使用静态代码块为Properties对象赋值
- 实例化一个Properties对象
- 获取properties文件的流对象
- 读取流对象
- 获取流对象后根据配置文件中的key值获取value值,该value值就是服务层和持久层实现类的全限定类名
根据bean名称获取bean对象的两种方式,单例和多例
多例:在获取bean对象时使用了newInstance关键字实例化,每次调用都会使用默认函数调用对象,有于多例的存在,假如我们在业务层实现类中定义一个全局变量(i),并赋予初值(i=1),那么多例的存在会使得每次都调用对象,每次都会对变量进行赋初值,如果在重写的接口的方法中循环打印该变量i的值并且i++,那么多例的存在使得循环打印的结果都为1.
单例:单例解决的就是多例中存在的问题,解决方式是使用一个map容器,用于存放我们的bean对象,然后要获取bean对象的value值时,直接根据key值返回value值即可,由于map容器的使用,从而就减少了newInstance的使用,从而就解决了多例的问题,在实际编程中我们大多选用单例的模式,可以减少程序间的耦合
具体的理解参照下列程序:
public class BeanFactory {
//定义一个Properties对象
private static Properties props ;
//定义一个Map容器,用于存放我们要创建的对象
private static Map<String,Object> beans;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取propertis文件的流对象
//不要采用new FileInputStream(),src路径和本地文件绝对路径都是会变的
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//读取流对象
props.load(in);
//实例化容器
beans = new HashMap<String, Object>();
//获取配置文件中所有的key
Enumeration 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();
//把key和value存入容器中
beans.put(key,value);
}
} catch (IOException e) {
throw new ExceptionInInitializerError("初始化properties文件失败");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 单例的
* @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);
bean = Class.forName(beanPath).newInstance();
//newInstance实例化 每次都会调用默认函数调用对象 所以是一种多例的现象
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}**/
}