Ioc是什么?

知道spring的话,自然知道Ioc,就是控制反转,把new class();的过程交给容器来控制。

实现一个简单的Ioc

过程只需4步:

  1. 加载xml配置文件,遍历标签。
  2. 获取标签中的id和class,加载class属性值的类,并创建bean。
  3. 遍历bean里面的标签,获取属性值,并填充bean对象中。
  4. 将bean对象注册到容器。

按照上面步骤,我们来编写代码。

// 实现Ioc 的实现类 SimpleIoc.java
public class SimpleIoc {
    // 定义bean容器
    private Map<String, Object> beanMap = new HashMap<>();
    
    SimpleIoc() throws Exception {
        loanBean();
    }

    /**
     * 获取bean对象
     * @param name
     * @return
     */
    public Object getBean(String name) {
        Object bean = beanMap.get(name);
        if (bean == null) {
            throw new IllegalArgumentException("referenced bean '" + name + "' is not found");
        }
        return bean;
    }

    /**
     * 解析XML, 装载Bean
     * @throws Exception
     */
    public void loanBean() throws Exception {
        InputStream input = SimpleIoc.class.getClassLoader().getResourceAsStream("ioc.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        Document document = documentBuilder.parse(input);
        Element root = document.getDocumentElement();
        NodeList nodeList = root.getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                String id = ele.getAttribute("id");
                String className = ele.getAttribute("class");

                Class beanClass = null;
                try {
                    beanClass = Class.forName(className);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    return;
                }

                Object bean = beanClass.newInstance();

                NodeList propertyNodes = ele.getElementsByTagName("property");
                for (int j = 0; j < propertyNodes.getLength(); j++) {
                    Node propertyNode = propertyNodes.item(i);
                    if (propertyNode instanceof Element) {
                        Element propertElement = (Element) propertyNode;
                        String name = propertElement.getAttribute("name");
                        String value = propertElement.getAttribute("value");

                        // 利用反射获取访问权限
                        Field declaredField = bean.getClass().getDeclaredField(name);
                        declaredField.setAccessible(true);

                        if (value != null && value.length() > 0) {
                            declaredField.set(bean, value);
                        } else {
                            String ref = propertElement.getAttribute("ref");
                            if (ref == null || ref.length() == 0) {
                                throw new IllegalArgumentException("ref error");
                            }
                            declaredField.set(bean, getBean(ref));
                        }

                        registerBean(id, bean);
                    }
                }
            }
        }
    }

    /**
     * bean注册到容器
     * @param id
     * @param bean
     */
    public void registerBean(String id, Object bean) {
        beanMap.put(id, bean);
    }
}

还需要定义几个Bean对象:

// Hand.java
public class Hand {
    private String color;
    private String size;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }
}

// People.java
public class People {
    private String eye;
    private String mouth;
    private String ear;
    private String foot;
    private Hand hand;

    public String getEye() {
        return eye;
    }

    public void setEye(String eye) {
        this.eye = eye;
    }

    public String getMouth() {
        return mouth;
    }

    public void setMouth(String mouth) {
        this.mouth = mouth;
    }

    public String getEar() {
        return ear;
    }

    public void setEar(String ear) {
        this.ear = ear;
    }

    public String getFoot() {
        return foot;
    }

    public void setFoot(String foot) {
        this.foot = foot;
    }

    public Hand getHand() {
        return hand;
    }

    public void setHand(Hand hand) {
        this.hand = hand;
    }
}

bean配置文件 ico.xml:

// 放在resource下
<?xml version="1.0" encoding="UTF-8"?>

<beans>
    <bean id="hand" class="com.zff.spring.ioc.Hand">
        <property name="color" value="yellow"/>
        <property name="size" value="big"/>
    </bean>

    <bean id="people" class="com.zff.spring.ioc.People">
        <property name="eye" value="two"/>
        <property name="mouth" value="one"/>
        <property name="ear" value="two"/>
        <property name="foot" value="two"/>
        <property name="hand" ref="hand"/>
    </bean>
</beans>

Main方法类,验证代码:

// Application.java
public class Application {
    public static void main(String[] args) throws Exception {
        SimpleIoc simpleIoc = new SimpleIoc();
        Hand hand = (Hand) simpleIoc.getBean("hand");
        People people = (People) simpleIoc.getBean("people");
        System.out.println(hand);
        System.out.println(people);

        System.out.println(hand.getSize());
    }
}

好了,以上就是简单实现Ico的过程。