1. 程式人生 > >純手寫springIOC

純手寫springIOC

 大家好啊~ 那麼今天來帶大家寫一下spring的ioc。

  其實也很簡單,首先我們明白兩點,java解析xml和java的反射機制,因為ioc就是主要是基於這兩個來實現,今天只是簡單的來大家實現下。

  廢話不多說直接上程式碼。

  1.首先加入maven依賴我們這裡用到的xml解析是dem4j,先看下專案結構吧。

  2.匯入maven依賴

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.gd</groupId> 8 <artifactId>mySpringIOC</artifactId> 9
<version>1.0-SNAPSHOT</version> 10 <packaging>jar</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>dom4j</groupId> 15 <artifactId>dom4j</artifactId> 16 <version>1.6.1</version> 17
</dependency> 18 </dependencies> 19 </project>

3.首先我們來看MyApplicationContext這個介面

package org.zgw.framework.spring.ioc;

/**
 * @DATA 2018-12-30 23:05
 * @Author zhangguowei  WeChat:17630376104
 * @Description TODO
 */
public interface MyApplicationContext {
    Object getBean(String beanId);

    Object getBean(Class clazz);
}

  這個介面中有個兩個getbBean();重栽的方法。這兩個介面也就是ioc的id大家用過spring 的應該都知道,這裡不過多的解釋。

4.接著看我們的MyClassPathXmlApplicationContext這個實現類。

package org.zgw.framework.spring.ioc;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.zgw.framework.spring.ioc.model.BeanDefinition;
import org.zgw.framework.spring.ioc.model.PropertyDefinition;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @DATA 2018-12-30 23:07
 * @Author zhangguowei  WeChat:17630376104
 * @Description TODO
 */
public class MyClassPathXmlApplicationContext implements MyApplicationContext {

    private Map<String, BeanDefinition> stringBeanDefinitionMap = new HashMap<String, BeanDefinition>();


    public MyClassPathXmlApplicationContext(String xmlName) {
        loadXml(xmlName);
    }

    private void loadXml(String xmlName) {
        SAXReader reader = new SAXReader();
//讀取xml InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlName); try { Document document = reader.read(inputStream); // 獲取標籤 Element element = document.getRootElement(); System.out.println("根節點:" + element.getName()); List<Element> elementList = element.elements(); for (Element beanlist : elementList) { System.out.println("子節點:" + beanlist.getName() + "\t" + beanlist.attributeValue("id") + "\t" + beanlist.attributeValue("class")); BeanDefinition beanDefinition = new BeanDefinition();
//讀取name的值 beanDefinition.setName(beanlist.attributeValue("name"));
//讀取class的值 beanDefinition.setClassStr(beanlist.attributeValue("class")); List<Element> proList = beanlist.elements(); for (Element element1 : proList) { System.out.println(element1.getName() + "\t" + element1.attributeValue("name") + "\t" + element1.getText()); PropertyDefinition propertyDefinition = new PropertyDefinition(); propertyDefinition.setName(element1.attributeValue("name")); propertyDefinition.setValue(element1.attributeValue("value")); beanDefinition.getPropertyDefinitionMap().put(propertyDefinition.getName(), propertyDefinition); } stringBeanDefinitionMap.put(beanDefinition.getName(), beanDefinition); } } catch (DocumentException e) { e.printStackTrace(); } } public Object getBean(String beanId) { BeanDefinition beanDefinition = stringBeanDefinitionMap.get(beanId); String clazzStr = beanDefinition.getClassStr(); Object beanobj = null; try { Class clazz = Class.forName(clazzStr); beanobj = clazz.newInstance(); // 給屬性賦值 Collection<PropertyDefinition> propertyDefinitions = beanDefinition.getPropertyDefinitionMap().values(); for (PropertyDefinition propertyDefinition : propertyDefinitions) { String setterMethodStr = propertyDefinition.getName();
//因為spring讀的是他個set方法,一般set方法都為大寫開頭所以這裡進行轉換 String firstChar = setterMethodStr.substring(0, 1).toUpperCase(); setterMethodStr = "set" + firstChar + setterMethodStr.substring(1); System.out.println("-------- 拼接出來的set方法" + setterMethodStr); Method setMathod= clazz.getMethod(setterMethodStr,String.class); setMathod.invoke(beanobj,propertyDefinition.getValue()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return beanobj; } public Object getBean(Class clazz) { return null; } }

  基本的註釋我都寫有,這些大家應該能看的懂。

5.還有一點就是兩個實體的類,因為她們得對應spring的屬性

package org.zgw.framework.spring.ioc.model;

import java.util.HashMap;
import java.util.Map;

/**
 * @DATA 2018-12-30 23:15
 * @Author zhangguowei  WeChat:17630376104
 * @Description TODO
 */
public class BeanDefinition {
    private String name;

    private String classStr;

    private Map<String, PropertyDefinition> propertyDefinitionMap = new HashMap<String, PropertyDefinition>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassStr() {
        return classStr;
    }

    public void setClassStr(String classStr) {
        this.classStr = classStr;
    }

    public Map<String, PropertyDefinition> getPropertyDefinitionMap() {
        return propertyDefinitionMap;
    }

    public void setPropertyDefinitionMap(Map<String, PropertyDefinition> propertyDefinitionMap) {
        this.propertyDefinitionMap = propertyDefinitionMap;
    }
}

  

package org.zgw.framework.spring.ioc.model;

/**
 * @DATA 2018-12-30 23:17
 * @Author zhangguowei  WeChat:17630376104
 * @Description TODO
 */
public class PropertyDefinition
{
    private String name;
    private String value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

  這個只是基於xml的ioc,直接上程式碼,可以拷貝走嘗試下,方便大家理解。後續還有ioc的註解方式實現。