Spring IoC模擬

Spring IoC(Inversion of Control)也叫DI(Dependency Injection)。
控制反轉指的是創建對象操作、對象屬性的賦值操作的控制權由業務代碼反轉到Spring容器。
依賴注入指的是對象的屬性賦值操作由Spring在容器中找到對應的對象后完成操作。
兩個術語表達的角度不同,但是同一個意思。也就是兩點:

  1. 對象的初始化交給Spring容器去做;
  2. 對象屬性的賦值交給Spring容器去做。

下面用簡易版的代碼,模擬通過XML配置完成Spring IoC的過程。
Spring IoC的基本實現過程是:
有一個Bean工廠,里面維護了一個Bean容器,在Bean工廠初始化的時候去解析配置文件。在配置文件中找到所有的<bean>,通過<bean>的id和class屬性來初始化成對應的bean對象,然后放到Bean容器里。比如下面的applicationContext.xml

<?xml version="1.0" encoding="utf-8"?>
<beans>
    <bean id="car" class="tk.zhun.j2se.ioc.Car" />
</beans>

然后寫一個BeanFactory的類來讀取它,并且初始化所有的bean到容器中。并提供一個從容器中通過類名獲取bean的方法getBean(String beanName):

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;

public class BeanFactory {
    private static HashMap<String,Object> container = new HashMap<>();

    public BeanFactory() throws Exception{
        InputStream ip = BeanFactory.class.getClassLoader()
                .getResourceAsStream("tk/zhun/j2se/ioc/applicationContext.xml");
        Document doc = null;
        SAXReader xmlReader = new SAXReader();
        doc = xmlReader.read(ip);
        Element root = doc.getRootElement();
        List<Element> beanList = root.elements("bean");
        for (Element bean:beanList) {
            String id = bean.attributeValue("id");
            String clazz = bean.attributeValue("class");
            Object o = Class.forName(clazz).newInstance();
            container.put(id,o);
        }
    }
    public Object getBean(String beanName) throws Exception {
        return container.get(beanName);
    }
}

測試代碼:

public class Car {
    public void run(){
        System.out.println("A car is running......");
    }
}
public class Client {
    public static void main(String[] args) throws Exception {
        BeanFactory beanFactory = new BeanFactory();
        Car car = (Car)beanFactory.getBean("car");
        car.run();
    }
}

運行結果:

A car is running......

TIP:這里只演示了第1步(對象的初始化交給Spring容器去做),第2步沒有實現,思路就是在解析XML之后,對<bean>中帶有<property>標簽的bean對象,通過反射獲取該屬性setter方法的Method對象,然后調用該Method對象的invoke方法,完成賦值。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容