在一个项目中实现解耦,需要用到工厂模式实现解耦
一个创建Bean对象的工厂,它就是创建Service、Dao对象的工厂
1>需要配置文件来配置Service、Dao(配置的内容:唯一标识=全限定类名)
2>通过读取配置文件中配置内容,反射创建对象(配置文件可以是xml或者是properties)
使用工厂模式实现解耦(抽取重用方法)
配置文件:
admainDao=tj.ustb.studentFunding.Dao.AdmainDao.java
admainService=tj.ustb.studentFunding.Service.AdmainService.java
创建BeanFactory工厂类,通过传入的参数BeanName,调用创建的静态Properties对象来获取配置文件中的全类名,获取后通过Class.forName()获取加载器,调用创建实例方法获取实例对象。
public class BeanFactory {
//定义一个Properties对象
private static Properties props;
//使用静态代码快为Properties对象赋值
static{
//实例化对象
Properties props = new Properties();
InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
props.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 根据Bean的名称获取Bean对象
* */
public static Object getBean(String BeanName){
Object bean = null;
try {
//通过key值得到对应Bean的全类名
String beanPath = props.getProperty(BeanName);
//通过全类名获取该类的加载器并且调用创建实例方法获取Bean
bean = Class.forName(beanPath).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bean;
}
}
因此,在耦合度高的类中调用BeanFactory类中的静态方法获取实例,
public class AdmainService {
AdmainDao admainDao = (AdmainDao)BeanFactory.getBean("admainDao");
/*
* 登录功能
* */
public Admain login(Admain form) throws StudentException{
Admain admain = admainDao.findByAdmainPassword(form);
if(admain == null) throw new StudentException("账号不存在或密码错误");
return admain;
}
}
此时,通过调用的newInstance方法生成的实例是多实例的,因此需要通过将反射调用newInstance()得到的实例放入Map,让其成为单实例对象。在BeanFactory类的静态代码块中,初始化容器beans(beans的本质是一个Map,key为Bean的类名,value为Bean实例)。通过配置文件获取所有key值,遍历枚举获得对应的key,props.getProperty(key)获取对应的全类名,使用类加载器将全类名作为参数,然后调用构造实例的方法,得到相应的实例。最后将key值和实例存入beans中。
public class BeanFactory {
//定义一个Properties对象
private static Properties props;
private static Map<String,Object> beans;
//使用静态代码快为Properties对象赋值
static{
//实例化对象
Properties props = new Properties();
InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
props.load(is);
//实例化容器
beans = new HashMap<String,Object>();
//通过Properties类对象调用keys方法得到枚举类集合
Enumeration keys = props.keys();
//遍历枚举
while(keys.hasMoreElements()){
String key = keys.nextElement().toString();
String path = props.getProperty(key);
//反射创建对象
Object value = null;
try {
value = Class.forName(path).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将key value存入容器中
beans.put(key, value);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 根据Bean的名称获取Bean对象
* */
public static Object getBean(String BeanName){
return beans.get(BeanName);
}
}
因此出现了IOC容器,IOC:控制反转,将创建对象的权利交给框架,因此这是框架的重要特征,其包括依赖注入(DI)和依赖查找(DL)