利用反射實現Spring的IOC容器
Spring的IOC簡介
概念
Spring的核心模塊就是IOC機制,IOC是Inversion Of Control簡稱。
Inversion 反轉
對象的獲得,原來由程序開發人員自己構造,變成了由Spring指定,由主動獲取變成了被動的接收。
Control 控制
控制的是對象的創建,原來由程序開發人員來創建一個對象,現在由Spring容器來創建對象
與MVC三層架構的區別
在MVC架構中,Service調用Dao層時就需要傳入一個Dao層的具體的實現類即可。
雖然dao仍然需要創建,但是在結構上卻發生了根本的變化,即:對象由原來程序本身創建,變爲了程序被動的接收對象。程序員的主要精力放在業務層的實現上。實現了service層和dao層的解耦工作,service層和dao層實現了分離,沒有了直接的依賴關係。如果dao層發生了業務的改變,原有的程序不需要發生任何改變,只需要將不同的dao實現類傳給Service即可。
Spring框架則實現了完全的解耦,在service對象創建時將會創建一個dao的對象傳入到service中,Spring將這種實現通過以下配置來完成。
步驟
1.首先創建一個簡單的pojo
package com.langsin.pojo;
public class Book {
private String bookId;
private String bookName;
public Double price;
public Book(String bookId,String bookName,Double price) {
this.bookId=bookId;
this.bookName = bookName;
this.price = price;
}
public Book(){
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public Book(String bookId, String bookName, Double price) {
this.bookId = bookId;
this.bookName = bookName;
this.price = price;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]";
}
}
2.在xml中配置Book的bean
<---! 引入了c命名空間->
<bean id="book" name="bo1,bo2"
class="com.langsin.pojo.Book" c:bookId="B001"
c:bookName="數學" c:price="12.25">
3.在pom.xml中加入jdom
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
4.創建一個beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="book" class="com.langsin.pojo.Book">
<attr property="bookName" value="Java基礎"/>
</bean>
<bean id="user" class="com.langsin.pojo.User">
<attr property="userName" value="張三"/>
</bean>
</beans>
5.利用反射手寫IOC並測試
public void testReflect() throws Exception{
//創建一個容器
Map<String,Object> container = new HashMap<>();
//自己實現的Spring的IOC容器
SAXBuilder builder = new SAXBuilder();
InputStream stream = new FileInputStream("./src/main/resources/beans.xml");
Document dom = builder.build(stream);
//獲取根節點
Element root = dom.getRootElement();
//返回的是子節點的集合
List<Element> children = root.getChildren();
for (Element child : children) {
//獲取類
String classPath = child.getAttributeValue("class");
//通過反射獲取類
Class<?> clazz = Class.forName(classPath);
//獲取對象的唯一標識
String id= child.getAttributeValue("id");
Object obj = clazz.newInstance();
container.put(id, obj);
List<Element> attrList = child.getChildren();
for (Element attr : attrList) {
String filed = attr.getAttributeValue("property");
String value = attr.getAttributeValue("value");
//通過反射獲取對應的方法
String name = this.getMethodName(filed);
Method method = clazz.getMethod(name, new Class[] {String.class});
method.invoke(obj, new Object[] {value});
}
}
System.out.println("ioc容器啓動");
Book book = (Book) container.get("book");
System.out.println(book.getBookName());
User user = (User) container.get("user");
System.out.println(user.getUserName());
}