三层结构的耦合性问
-
存在的问题
-
各层级接口问题,使用依赖倒置原则解决
-
对象创建使用构造器,如果构造器发生改变,所有使用到的地方都要修改,使用工厂模式解决
-
尽量减少导包操作,使用反射创建对象
-
尽量减少字符串硬编码问题,使用配置文件存储对应的字符串
-
通过工厂模式获取对象
public class MyApplicationContext {
public Object getBean(String beanName){
if ("userService".equals(beanName)) {
return new UserServiceImpl();
} else if ("userDao".equals(beanName)) {
return new UserDaoImpl();
} else if ("user".equals(beanName)) {
return new User();
}
return null;
}
}
存在的问题 : if-else 分支太多 当需要获取其他对象时需要改动代码
import太多
解决方案 通过反射获取对象
public class MyApplicationContext {
/**
*
* @param className : 全限定类名
* @return
*/
public Object getBean(String className){
try {
Object obj = Class.forName(className).newInstance();
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
存在的问题: 存在大量的字符串硬编码 因为获取对象时需要传入类的全限定名
解决方案: 引入xml配置 通过dom4j 解析配置文件 获取对象
public class MyApplicationContext {
private String configLocation;
private Map<String, Object> map = new HashMap<String, Object>();
public MyApplicationContext(String configLocation) {
this.configLocation = configLocation;
//1,MyApplicationContext一初始化就立马解析beans.xml
parseXML(configLocation);
}
/**
* 解析xml
*/
private void parseXML(String configLocation) {
//创建核心解析器
SAXReader saxReader = new SAXReader();
//加载beans.xml,获取对应inputStream
InputStream inputStream = MyApplicationContext.class.getClassLoader().getResourceAsStream(configLocation);
try {
//读取该inputStream,获取对应xml文档对象
Document document = saxReader.read(inputStream);
Element rootElement = document.getRootElement();
List<Element> beanEles = rootElement.elements("bean");
for (Element beanEle : beanEles) {
//获取bean对象的唯一标识
String id = beanEle.attributeValue("id");
//获取bean对象的全限定类名
String className = beanEle.attributeValue("class");
//2,根据xml配置的class属性使用反射创建对象,并根据id属性存储对象
Object obj = Class.forName(className).getConstructor().newInstance();
map.put(id, obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取对象
* @param beanName : 对象名称
* @return
*/
public Object getBean(String beanName) {
return map.get(beanName);
}
}
在使用此工具类时 通过解析传入的xml文件 创建一个Map 作为存储对象的容器 从map中获取对象
IoC控制反转
-
概述
-
IoC : inversion of controller , 控制反转
-
对资源(对象)的控制权进行反转
-
-
控制反转
使用Spring的IoC解决程序耦合
-
-
控制反转
-
控制
-
原来,由程序直接控制使用资源
-
现在,由spring容器控制和提供资源,程序等待资源被提供
-
-
反转
-
资源的控制权由原来的程序交给Spring容器
-
-
-
好处
-
降低资源之间的耦合度
-
可以对资源进行合理有效地管理
-