程序间的依赖关系。
在开发过程中一个项目是需要许多人共同完成的,类与类之间存在依赖关系,如果不解决依赖关系,A的类没有写完,B完全不能工作需要等待A写完才能写,要解决这个问题就需要使用反射功能解决,减少使用new XXX的使用创建实例,确保在写代码的时候编译过程中不报错。
开发时遵循的原则:
编译时不依赖,运行时才依赖。
解决依赖关系:
使用反射创建类对象。
使用反射创建类对象引发的新问题:
使用配置文件,通过读取配置文件来反射创建类对象
比如数据库绑定驱动
Class.forName(“com.mysql.jdbc.Driver”);
模拟解决项目依赖的小实验
[email protected]:sorryapologize/springtest.git
//cn.pro.dao.ICustormerDao
package cn.pro.dao;
//模拟一个客户dao
public interface ICustormerDao {
//保存客户
void SaveCustormer();
}
cn.pro.dao.impl.ICustormerDaoimpl
package cn.pro.dao.impl;
import cn.pro.dao.ICustormerDao;
//模拟客户持久层实现类
public class ICustormerDaoimpl implements ICustormerDao{
@Override
public void SaveCustormer() {
// TODO Auto-generated method stub
System.out.println("持久层保存了客户");
}
}
cn.pro.factory.BeanFactory
package cn.pro.factory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;
import cn.pro.dao.ICustormerDao;
import cn.pro.service.CustormerService;
public class BeanFactory {
//读取properties文件
//a 定义一个properties对象
/*private static Properties props =null;
//b定义静态代码块
static{
try {
InputStream in = BeanFactory.class.getClassLoader()
.getResourceAsStream("bean.properties");
//InputStream in = new FileInputStream("src/bean.properties"); 不要使用在web工程中会报空指针
props.load(in);
} catch (Exception e) {
// TODO: handle exception
throw new ExceptionInInitializerError("读取配置文件失败" + e);
}
}*/
//1.上面那么多可用于下面一句 它只能用于读取properties文件别的文件读不了
//2.只能用于读取,不能用于写入。
//3.只能用于读取类路径下的文件
//注意参数的写法是按照包名类名的方式写的,所以请不要写扩展名。
private static ResourceBundle bundle= ResourceBundle.getBundle("bean");
public static Object getBean(String beanName){
try {
//1.读取配置文件,根据beanName获取全限定类名
//String beanPath=props.getProperty(beanName);
String beanPath=bundle.getString(beanName);
return Class.forName(beanPath).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
//下面方法的局限性比较大,一个方法只能返回一个对象
/*public static CustormerService getCustormerService(){
try {
return (CustormerService) Class.forName("cn.pro.service.impl.CustormerServiceimpl").newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
public static ICustormerDao getICustormerDao(){
try {
return (ICustormerDao) Class.forName("cn.pro.dao.impl.ICustormerDaoimpl").newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}*/
}
cn.pro.service.CustormerService
package cn.pro.service;
//客户的业务实现接口
public interface CustormerService {
void saveCustormer();
}
cn.pro.service.impl.CustormerServiceimpl
package cn.pro.service.impl;
import cn.pro.dao.ICustormerDao;
import cn.pro.dao.impl.ICustormerDaoimpl;
import cn.pro.factory.BeanFactory;
import cn.pro.service.CustormerService;
//客户的业务层实现层
public class CustormerServiceimpl implements CustormerService{
//ICustormerDao custormerdao = new ICustormerDaoimpl();
//ICustormerDao custormerdao = BeanFactory.getICustormerDao();
private ICustormerDao custormerdao = (ICustormerDao) BeanFactory.getBean("CUSTORMERDAO");
@Override
public void saveCustormer() {
// TODO Auto-generated method stub
System.out.println("custormer saved!");
custormerdao.SaveCustormer();
}
}
cn.pro.ui.Client
package cn.pro.ui;
import cn.pro.factory.BeanFactory;
import cn.pro.service.CustormerService;
import cn.pro.service.impl.CustormerServiceimpl;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//CustormerService service = new CustormerServiceimpl();
//上面代码改成下面代码就解决了依赖关系
//CustormerService service =BeanFactory.getCustormerService();
CustormerService service = (CustormerService) BeanFactory.getBean("CUSTORMERSERVICE");
service.saveCustormer();
}
}
改造上述main方法
for (int i=0;i<5;i++){
CustormerService service = (CustormerService) BeanFactory.getBean("CUSTORMERSERVICE");
//service.saveCustormer();
System.out.println(service);
}
输出:
cn.pro.service.impl.CustormerServiceimpl@8814e9
cn.pro.service.impl.CustormerServiceimpl@1503a3
cn.pro.service.impl.CustormerServiceimpl@1a1c887
cn.pro.service.impl.CustormerServiceimpl@743399
cn.pro.service.impl.CustormerServiceimpl@e7b241
当多个客户端访问的时候创建了多个对象,怎么改造上面代码,当多个客户端访问的时候只穿件一个对象。
改写代码cn.pro.factory.BeanFactory
package cn.pro.factory;
import java.beans.Beans;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import cn.pro.dao.ICustormerDao;
import cn.pro.service.CustormerService;
public class BeanFactory {
//读取properties文件
//a 定义一个properties对象
/*private static Properties props =null;
//b定义静态代码块
static{
try {
InputStream in = BeanFactory.class.getClassLoader()
.getResourceAsStream("bean.properties");
//InputStream in = new FileInputStream("src/bean.properties"); 不要使用在web工程中会报空指针
props.load(in);
} catch (Exception e) {
// TODO: handle exception
throw new ExceptionInInitializerError("读取配置文件失败" + e);
}
}*/
//1.上面那么多可用于下面一句 它只能用于读取properties文件别的文件读不了
//2.只能用于读取,不能用于写入。
//3.只能用于读取类路径下的文件
//注意参数的写法是按照包名类名的方式写的,所以请不要写扩展名。
private static ResourceBundle bundle= ResourceBundle.getBundle("bean");
//定义一个容器存放我们要使用的对象
private static Map beans = new HashMap();
//使用静态代码块初始化map
static{
try {
//1.读取配置文件中所有的配置key的部分
Enumeration keys = bundle.getKeys();
//2.遍历keys
while (keys.hasMoreElements()) {
//取出key
String key = (String) keys.nextElement();
//根据key获取beanpath
String beanpath = bundle.getString(key);
//根据beanpath反射创建类对象
Object value = Class.forName(beanpath).newInstance();
//把key和value存入map
beans.put(key, value);
}
} catch (Exception e) {
// TODO Auto-generated catch block
throw new ExceptionInInitializerError("创建容器失败程序停止执行");
}
}
public static Object getBean(String beanName){
return beans.get(beanName);
}
//下面方法的局限性比较大,一个方法只能返回一个对象
/*public static CustormerService getCustormerService(){
try {
return (CustormerService) Class.forName("cn.pro.service.impl.CustormerServiceimpl").newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
public static ICustormerDao getICustormerDao(){
try {
return (ICustormerDao) Class.forName("cn.pro.dao.impl.ICustormerDaoimpl").newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}*/
}
重新执行
cn.pro.service.impl.CustormerServiceimpl@e83912
cn.pro.service.impl.CustormerServiceimpl@e83912
cn.pro.service.impl.CustormerServiceimpl@e83912
cn.pro.service.impl.CustormerServiceimpl@e83912
cn.pro.service.impl.CustormerServiceimpl@e83912
可以看到service对象只有一个。