加深spring架構了解,實作簡單的Ioc容器
最近學習到了SSM架構,記錄一下spring的Ioc容器學習。
什麼是Ioc?
Ioc 英文就是 Inversion Of Control,意思是控制反轉。
IoC 是指在程式開發中,執行個體的建立不再由調用者管理,而是由 Spring 容器建立。Spring 容器會負責控制程式之間的關系,而不是由程式代碼直接控制,是以,控制權由程式代碼轉移到了 Spring 容器中,控制權發生了反轉,這就是 Spring 的 IoC 思想。
簡單一點說,就是以前我們建立對象的時候,要自己敲,new 一個新對象,現在把建立對象的任務交給spring容器處理,由spring容器建立對象,我們直接使用就好。
思想簡單了解
我們将需要建立的對象和依賴關系通過bean标簽的形式寫入配置檔案(applicationContext.xml),架構讀取配置檔案,建立對象并處理依賴關系。
寫一個簡單的Ioc容器
建立實體對象類,将類資訊寫入applicationContext.xml檔案,初始化容器,讀取配置檔案,獲得類資訊,資料資訊,利用反射機制獲得類對象,建立類,将資料注入類。
實作
1.建立項目
項目名 easyIoc,結構如下
2.實體類:Apple
package com.Ioc.entity;
public class Apple {
private String name;
private String color;
private String taste;
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", taste='" + taste + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
}
3.配置檔案:applicationContext.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="redApple" class="com.Ioc.entity.Apple">
<property name="name" value="紅蘋果"/>
<property name="color" value="紅色"/>
<property name="taste" value="甜"/>
</bean>
</beans>
4.接口類:applicationContext
package com.Ioc.context;
public interface ApplicationContext {
public Object getBean(String beanId);
}
5.實作類:ClassPathXmlApplicationContext
package com.Ioc.context;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
private Map IocContainer = new HashMap();
public ClassPathXmlApplicationContext() {
try {
// 讀取xml配置檔案
// getResource用于從classpath擷取指定檔案資源 getPath擷取路徑
String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
// URL解碼,防止出現中文路徑丢失問題
filePath = new URLDecoder().decode(filePath, "UTF-8");
// 加載解析xml檔案,獲得Document對象
SAXReader reader = new SAXReader();
Document document = reader.read(new File(filePath));
// 擷取根節點集合
List<Node> beans = document.getRootElement().selectNodes("bean");
for (Node node : beans) {
// 強制轉換成Element對象
Element element = (Element) node;
// 提取屬性
String id = element.attributeValue("id");
String className = element.attributeValue("class");
// 利用java反射擷取類對象
Class c = Class.forName(className);
// 接收類對象
Object obj = c.newInstance();
// 獲得屬性節點
List<Node> propertys = element.selectNodes("property");
for (Node property : propertys) {
Element ele = (Element) property;
// 獲得屬性名和屬性值
String name = ele.attributeValue("name");
String value = ele.attributeValue("value");
// 動态注入
// 定義方法名,set後第一個字元大寫
String setMethodName = "set" + name.substring(0,1).toUpperCase()+name.substring(1);
System.out.println("準備執行" + setMethodName + "方法注入資料");
// 利用反射,通過方法名調用方法
// getMethod(),第一個參數:方法名,第二個參數:方法的參數的類型
Method setMethod = c.getMethod(setMethodName, String.class);
// 調用方法
setMethod.invoke(obj, value);//通過setter方法注入資料
}
// 放入容器
IocContainer.put(id, obj);
}
System.out.println(IocContainer);
System.out.println("初始化完成");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String beanId) {
return IocContainer.get(beanId);
}
}
6.導入依賴:dom4j和jaxen (pom.xml)
<dependencies>
<!--dom4j: java的xml解析元件,底層依賴jaxen-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--jaxen:Xpath表達式解釋器-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
7.程式入口:Application
package com.Ioc;
import com.Ioc.context.ApplicationContext;
import com.Ioc.context.ClassPathXmlApplicationContext;
import com.Ioc.entity.Apple;
public class Application {
public static void main(String[] args) {
// 初始化容器
ApplicationContext context = new ClassPathXmlApplicationContext();
System.out.println((Apple)context.getBean("redApple"));
}
}
8.結果
結語
有問題希望大家指出。學無止境,歡迎交流。