通过反射技术来创建实例对象
- 可以降低类之间的耦合性
- 对于不存在的类,出现的不是error异常(编译时),而是NotFoundException异常(运行时)
工厂类
package com.itheima.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 一个创建Bean对象的工厂
*
* Bean:在计算机英语中,有可重用组的含义
* JavaBean:用Java语言编写的可重用组件
* JavaBean > 实体类
* 它就是创建我们的service和dao对象的
*
* 第一个:需要一个配置文件配置我们的service和dao
* 配置的内容: 唯一标识=全限定类名(key=value)
* 第二个:通过读取配置文件中的配置内容,反射创建对象
*/
public class BeanFactory
{
//定义一个Properties对象
private static Properties props;
//使用静态代码块为Properties对象赋值
static{
try{
//实例化对象
props = new Properties();
//获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失败!");
}
}
/**
* 根据Bean的名称获取Bean对象
*/
public static Object getBean(String beanName)
{
Object bean = null;
try{
String beanPath = props.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
}catch (Exception e)
{
e.printStackTrace();
}
return bean;
}
}
配置文件
accountService=com.itheima.service.impl.AccountServiceImpl
accountDao=com.itheima.dao.impl.AccountDaoImpl
package com.itheima.ui;
import com.itheima.factory.BeanFactory;
import com.itheima.service.IAccountService;
public class Client
{
public static void main(String[] args)
{
for(int i = 0; i < 5; i++)
{
IAccountService service = (IAccountService) BeanFactory.getBean("accountService");
System.out.println(service);
service.saveAccount();
}
}
}
运行结果可以看出,这种工厂,创建了多个实例对象(多例)
多例模式相比于单例模式,效率更低。
对于单例模式来说:实例的方法如果访问了外部对象,可以将外部对象放入到方法体内,这样,每次执行这个方法的效果就与多例模式一样了
so: =》转单例工厂
-- 通过Map来存放对象
-- 通过Map来提取对象
package com.itheima.factory;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 一个创建Bean对象的工厂
*
* Bean:在计算机英语中,有可重用组的含义
* JavaBean:用Java语言编写的可重用组件
* JavaBean > 实体类
* 它就是创建我们的service和dao对象的
*
* 第一个:需要一个配置文件配置我们的service和dao
* 配置的内容: 唯一标识=全限定类名(key=value)
* 第二个:通过读取配置文件中的配置内容,反射创建对象
*/
public class BeanFactory
{
//定义一个Properties对象
private static Properties props;
//定义一个Map, 用来存放我们要创建的对象,我们把它称之为容器
private static Map<String, Object> beans;
//使用静态代码块为Properties对象赋值
static{
try{
//实例化对象
props = new Properties();
//获取properties文件的流对象
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();
//得到相应的value
String beanPath = props.getProperty(key);
//创建相应的实例对象
Object value = Class.forName(beanPath).newInstance();
//把key、value存入到容器中
beans.put(key, value);
}
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失败!");
}
}
/**
* 根据Bean的名称获取Bean对象
*/
// public static Object getBean(String beanName)
// {
// Object bean = null;
// try{
// String beanPath = props.getProperty(beanName);
// bean = Class.forName(beanPath).newInstance();
// }catch (Exception e)
// {
// e.printStackTrace();
// }
// return bean;
// }
/**
* 根据bean的名称获取对象
*/
public static Object getBean(String beanName)
{
return beans.get(beanName);
}
}
package com.itheima.service.impl;
import com.itheima.dao.IAccountDao;
import com.itheima.dao.impl.AccountDaoImpl;
import com.itheima.factory.BeanFactory;
import com.itheima.service.IAccountService;
import sun.awt.geom.AreaOp;
/**
* 账户的业务层实现类
*/
public class AccountServiceImpl implements IAccountService
{
// private IAccountDao accountDao = new AccountDaoImpl();
private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
public void saveAccount()
{
int i = 0;
System.out.println(i);
accountDao.saveAccount();
i++;
}
}