簡單實現以下Spring的IOC

SpringIOC的簡單實現

1. spring IOC簡介

ioc: 全文是Inversion of Control。翻譯過來就是控制反轉,意思是對象之間的關係不再由傳統的程序來控制,而是由spring容器來統一控制這些對象創建、協調、銷燬,而對象只需要完成業務邏輯即可。

2. IOC的簡單實現

  1. 加載 xml 配置文件,遍歷其中的標籤
  2. 獲取標籤中的 id 和 class 屬性,加載 class 屬性對應的類,並創建 bean
  3. 遍歷標籤中的標籤,獲取屬性值,並將屬性值填充到 bean 中
  4. 將 bean 註冊到 bean 容器中

測試使用的實體類一 :Car

/**
 * @author crazyang
 * @date 2019/8/21
 * @Description:
 */
public class Car {
    private String name;
    private String length;
    private String width;
    private String height;
    private Wheel wheel;
    //省略getter/setter
}

測試使用的實體類二:Wheel

/**
 * @author crazyang
 * @date 2019/8/21
 * @Description:
 */
public class Wheel {
    private String brand;
    private String specification;
     //省略getter/setter
}

springIoc的簡單實現類

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author crazyang
 * @date 2019/8/21
 * @Description:
 */
public class SimpleIOC {

    private Map<String, Object> beanMap = new HashMap<>();

    public SimpleIOC(String location) throws Exception {
        loadBeans(location);
    }

    public Object getBean(String name) {
        Object bean = beanMap.get(name);
        if (bean == null) {
            throw new IllegalArgumentException("there is no bean with name" + name);
        }
        return bean;
    }

    private void loadBeans(String location) throws Exception {
        //加載xml配置文件
        InputStream inputStream = new FileInputStream(location);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = factory.newDocumentBuilder();
        Document doc = docBuilder.parse(inputStream);
        Element root = doc.getDocumentElement();
        NodeList nodes = root.getChildNodes();

        //遍歷<bean>標籤
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if (node instanceof Element) {
                Element element = (Element) node;
                String id = element.getAttribute("id");
                String className = element.getAttribute("class");
                //加載beanClass
                Class beanClass = null;
                try {
                    beanClass = Class.forName(className);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    return;
                }
                //創建bean
                Object bean = beanClass.newInstance();
                //遍歷<property>標籤
                NodeList propertyNodes = element.getElementsByTagName("property");
                for (int j = 0; j < propertyNodes.getLength(); j++) {
                    Node propertyNode = propertyNodes.item(j);
                    if (propertyNode instanceof Element) {
                        Element propertyElement = (Element) propertyNode;
                        String name = propertyElement.getAttribute("name");
                        String value = propertyElement.getAttribute("value");
                        //利用反射將bean相關字段訪問權限設爲可訪問
                        Field declareField = bean.getClass().getDeclaredField(name);
                        declareField.setAccessible(true);
                        if (value != null && value.length() > 0) {
                            declareField.set(bean, value);
                        } else {
                            String ref = propertyElement.getAttribute("ref");
                            if (ref == null && ref.length() == 0) {
                                throw new IllegalArgumentException("ref config error");
                            }
                            //將引用填充到相關字段中
                            declareField.set(bean, getBean(ref));
                        }
                        //將bean註冊到bean容器中
                        registerBean(id, bean);
                    }
                }

            }
        }

    }

    private void registerBean(String id, Object bean) {
        beanMap.put(id, bean);
    }
}

springIOC的配置文件,路徑是放在resource下面

<beans>
    <bean id="wheel" class="com.yangzhou.utils.Spring.ioc.Wheel">
        <property name="brand" value="Michelin"/>
        <property name="specification" value="265/60 R18"/>
    </bean>

    <bean id="car" class="com.yangzhou.utils.Spring.ioc.Car">
        <property name="name" value="Mercedes Benz G 500"/>
        <property name="length" value="4717mm"/>
        <property name="width" value="1855mm"/>
        <property name="height" value="1949mm"/>
        <property name="wheel" ref="wheel"/>
    </bean>
</beans>

springIoc的測試類

/**
 * @author zhouyang
 * @date 2019/8/21
 * @Description:
 */
public class SpringIOCTest {

    public static void main(String[] args)throws Exception {
        String path = "D:\\project\\test\\utils\\src\\main\\resources\\spring-test.xml";
        String location = SpringIOCTest.class.getClassLoader().getResource("spring-test.xml").getFile();
        SimpleIOC bf = new SimpleIOC(location);
        Wheel wheel = (Wheel) bf.getBean("wheel");
        System.out.println(wheel);
        Car car = (Car) bf.getBean("car");
        System.out.println(car);
        System.out.println(car.getName());
    }
}

輸出結果:

com.yangzhou.utils.Spring.ioc.Wheel@5a07e868
com.yangzhou.utils.Spring.ioc.Car@76ed5528
Mercedes Benz G 500
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章