自定義ioc
1.IOC
控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。
控制反轉,對象的使用者不是創建者 .
2.原始方式
特點:創建累,根據類自己new對象
優點:易寫,簡潔
缺點:耦合度太高,不方便維護
3.面向接口
特點:創建接口(規則),根據接口編寫實現類(可以是多個),根據實現類自己new對象. 對象不使用實現類接收了, 用接口(多態)
好處: 規範了. 相對原始方式 好維護了一點
缺點: 多寫了接口, 還是改了源碼
4.IOC
特點: 創建接口(規則), 根據接口編寫實現類(可以是多個). 編寫配置文件, 使用工廠模式創建對象出來. 要使用的話直接從工廠裏面獲得, 不再自己創建了
好處: 解耦了, 不需要修改源碼
缺點: 多寫了配置文件
自定義IOC代碼實現:
1.配置xml文件:
<?xml version = "1.0" encoding = "utf-8"?>
<beans>
<!--id屬性: 作爲bean的唯一標識, 隨便寫的 不要重複就好了【一般寫接口/類名, 首字母小寫】
class屬性: 類的全限定名
-->
<bean id="userDao" class="com.donjor.dao.impl.UserDaoImplMyBatis"></bean>
<bean id="userService" class="com.donjor.service.impl.UserServiceImpl"></bean>
</beans>
2.創建Bean工廠
package com.donjor.utils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description: 創建Bean的工廠
* 【問題】:
* 1.每次getBean()都需要解析一次xml
* 2.每次getBean()都是最後臨時反射創建一個對象返回
* 【解決】
* 1.xml只需要解析一次, 解析xml代碼定義在靜態代碼塊裏面
* 2.程序初始化的時候, 就解析xml 把所有bean創建好,存到一個容器(集合). getBean()時候就直接從容器裏面取
* 【容器】
* 1.容器選擇Map
* 2.把id作爲map的鍵, 把id對應的bean對象作爲map的值
*/
public class BeanFactory {
//容器
private static Map<String, Object> beanMap = new HashMap<String, Object>();
static {
InputStream is = null;
try {
//1.解析xml 獲得所有的bean標籤List
//1.1 創建SAXReader對象
SAXReader saxReader = new SAXReader();
//1.2 讀取xml 獲得document對象
is = BeanFactoryOri.class.getClassLoader().getResourceAsStream("applicationContext.xml");
Document document = saxReader.read(is);
List<Element> beanEles = document.selectNodes("//bean");
//2.遍歷所有的bean標籤List
for (Element beanEle : beanEles) {
//3.獲得bean標籤的id和class
String id = beanEle.attributeValue("id");
String className = beanEle.attributeValue("class");
//4.根據class反射創建對象, 把id作爲key,把對象作爲value存到beanMap
Object obj = Class.forName(className).newInstance();
beanMap.put(id, obj);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 根據id獲得對應的Bean對象
*
* @param id
* @return
*/
public static Object getBean(String id) { //eg: userDao
return beanMap.get(id);
}
}
通過自定義的Bean工廠,就實現了控制反轉,對象的使用者不是創建者 .