简易spring的IOC实现
    首先需要理解一下什么叫做ioc(inversion of Controller),简单来说就是控制反转。它不是一门像js这样的技术,我们可以把它看做一种设计模式。为什么会出现IOC呢?
    传统的程序会导致类与类之间高耦合,难以测试,于是就把创建和查找依赖对象的控制权都交给一个容器,由容器来进行注入组合对象。这里可以把容器比作一个菜篮,以前没有菜篮的时候去买白菜的时候就特别不方便,后来有了篮子,不仅装东西方便,而且还送货上门,你只需要说一声,我需要白菜,直接送到家门口。spring就相当于这个篮子。它体现了一个法则:“不管怎样都不要来找我们,我们有需要的时候回来找你的”。接下来我就把一个简易的spring的IOC展示出来。
主要步骤
- 写一个IOC的类,用来解析配置文件,当然配置文件有很多种,但是这里我就用了一个xml的配置文件。这里面要用到反射的知识。
 - 遍历xml文件中的所有的bean标签
 - 获取bean标签里面的id和class属性,加载class对应的类,并创建bean
 - 获取property标签的属性值,并填充到bean中
 - 将bean注册到bean容器中
 
主要文件
- 首先有一个xml文件,我给它取名为springIoc
 - 然后是读取xml文件的
MySimpleIOC文件  - 然后有实体类,也就是model,我这里用了Student和studentClass
 - 最后就是一个测试类(我用的是junit进行的测试)
 
关键代码展示[^code]
| 这里主要是读取xml文件的整个过程,也是整个实现IOC的关键,至于其他的就不做过多的阐述 | 
public MySimpleIOC(String location) throws Exception{
    loadBeans(location);
}
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 = ((Node) root).getChildNodes();
    for(int i = 0;i < nodes.getLength();i++){
        Node 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 properNode  = (Node) propertyNodes.item(j);
                if(properNode instanceof Element){
                    Element propertyElement = (Element) properNode;
                    String name = propertyElement.getAttribute("name");
                    String value = propertyElement.getAttribute("value");
                    //利用反射将bean相关字段访问权限设为可访问
                    Field declaredField = bean.getClass().getDeclaredField(name);
                    String tString = declaredField.getType().getName();
                    declaredField.setAccessible(true);
                    if(value != null && value.length() > 0){
                        if(tString.equals("java.lang.Integer")){
                            Integer temp = Integer.parseInt(value);
                            declaredField.set(bean, temp);
                        }else{
                            //将属性填充到相关字段中
                            declaredField.set(bean, value);
                        }
                    }else{
                        String ref = propertyElement.getAttribute("ref");
                        if(ref == null || ref.length() == 0){
                            throw new IllegalArgumentException("ref config error");
                        }
                        //将引用填充到相关字段中
                        declaredField.set(bean, getBean(ref));
                    }
                    //将bean注册到bean容器中
                    registerBean(id,bean);
                }
            }
        }
    }
}
private void registerBean(String id, Object bean) {
    beanMap.put(id, bean);
}
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;
}
刚刚说了关键就是上面那个步骤,下面我将测试类代码也展示一下。
 @Test
public void getBean() throws Exception{
    String location = MySimpleIOC.class.getClassLoader().getResource("springIoc.xml").getFile();
    String temp = location.substring(1, location.length());
    MySimpleIOC ioc = new MySimpleIOC(temp);
    StudentClass studentClass = (StudentClass) ioc.getBean("studentClass");
    System.out.println(studentClass + "," +studentClass.getCode() +","+ studentClass.getMark());
    Student student = (Student) ioc.getBean("student");
    System.out.println(student+"," +student.getName()+","+student.getStudentClass().getCode());
}