在學習spring一開始,書上就會提及spring中ioc(控制反轉)和aop(面向切面)是兩個重點内容。
那麼究竟什麼是ioc呢,下面就簡單總結一下ioc:(ps:關于spring的aop及其他知識将下後續文章總結)
IoC不是一種技術,隻是一種思想,一個重要的面向對象程式設計的法則,它能指導我們如何設計出松耦合、更優良的程式。傳統應用程式都是由我們在類内部主動建立依賴對象,進而導緻類與類之間高耦合,難于測試;有了IoC容器後,把建立和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,是以對象與對象之間是松散耦合,這樣也友善測試,利于功能複用,更重要的是使得程式的整個體系結構變得非常靈活。
其實IoC對程式設計帶來的最大改變不是從代碼上,而是從思想上,發生了“主從換位”的變化。應用程式原本是老大,要擷取什麼資源都是主動出擊,但是在IoC/DI思想中,應用程式就變成被動的了,被動的等待IoC容器來建立并注入它所需要的資源了。
IoC很好的展現了面向對象設計法則之一—— 好萊塢法則:“别找我們,我們找你”;即由IoC容器幫對象找相應的依賴對象并注入,而不是由對象主動去找。
IoC和DI由什麼關系呢?其實它們是同一個概念的不同角度描述,由于控制反轉概念比較含糊(可能隻是了解為容器控制對象這一個層面,很難讓人想到誰來維護對象關系),是以2004年大師級人物Martin Fowler又給出了一個新的名字:“依賴注入”,相對IoC 而言,“依賴注入”明确描述了“被注入對象依賴IoC容器配置依賴對象”。IOC的了解
那麼接下來就開始我們的模拟:
User.java:
package h.l.ioc;
public class User {// 使用者類
private String username;// 賬号
private String password;// 密碼
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
IOC.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="user2" class="club.j208.demo.User2"></bean>
<bean id="user" class="h.l.ioc.User"></bean>
</beans>
IOCByself.java:
/**
* @Title: IOCByself.java
* @Package h.l.ioc
* @Description: 模拟spring中IOC底層實作
* @author HL
* @version V1.0
*/
package h.l.ioc;
import java.io.File;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/************************************************************************
* 1、使用dom4j解析xml配置檔案 2、擷取配置檔案中指定bean的class屬性 3、得到屬性值使用反射建立對象 *
***********************************************************************/
public class IOCByself {
// 解析XML檔案
public Document parseXML(File file) {
SAXReader saxReader = new SAXReader();
Document document = null;
try {
document = saxReader.read(file);
} catch (DocumentException e) {
System.out.println(e.getMessage());
}
return document;
}
/**
* bean的格式<bean id="" class=""/>
*
* @param beanId傳入bean的id
* @return 建立bean的id對應的類的對象
*/
public Object getService(String beanId) {
Document document = parseXML(new File("src/h/l/ioc/IOC.xml"));
Element root = document.getRootElement();
String className="";
for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
Element element = it.next();
if(element.valueOf("@id").equals(beanId)) {
className=element.valueOf("@class");
}
}
Object object=null;
try {
Class<?> clazz=Class.forName(className);
object=clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
}
IOCByselfTest.java:
/**
* @Title: IOCByselfTest.java
* @Package h.l.ioc
* @Description: 測試
* @author HL
* @version V1.0
*/
package h.l.ioc;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class IOCByselfTest {
IOCByself iocByself = null;
@BeforeEach
void setUp() throws Exception {
iocByself = new IOCByself();
}
@Test
void test() {
User user = (User) iocByself.getService("user");
user.setUsername("Is-Me-HL");
user.setPassword("root");
System.out.println(user);
}
}
OK,Just do it!
注:以上文章僅是個人學習過程總結,若有不當之處,望不吝賜教。