IoC underlying principle

cutting edge:

  • Inversion of Control (IoC) is a design principle in object-oriented programming that can be used to reduce the coupling between codes. The most common method is called Dependency Injection (DI), and another method is called Dependency Lookup. IoC can be considered a brand-new design model, but the theory and time are relatively late, and it is not included in GoF.
  • The object b of Class B is used in Class A. In general, you need to explicitly new a B object in the code of A.
    After using dependency injection technology, A's code only needs to define a private B object, and does not need to directly obtain this object with new. Instead, the B object is externally new and injected into the A class through the relevant container control program. In reference. The specific acquisition method and the state of the object when it is acquired are specified by the configuration file (such as XML). That is to say, the object creation and the calling process between objects are handed over to Spring for management.

1. The main technology used in the bottom layer

  • xml parsing
  • Factory mode
  • reflection

Now we start to explain:
first look at the following code:

public class Person {
    
    
    public void eat(){
    
    
        System.out.println("吃饭!");
    }
}

public class Student {
    
    
    private Person person = new Person();

    public void eatForStudent(){
    
    
        person.eat();
        System.out.println("喝牛奶!");
    }
}

Person needs to be used in the Student class. At this time, our general approach is to new a Person object in the Student class, and then call its methods through this object, but have we ever thought about if the Person class changes, such as class The name has changed, and the path of the class has changed. If the Person object is also created in other classes, if the Person class object is also created in other classes, a lot of changes to the class path or name are required at this time, which is very troublesome. At this time, we can use the following factory model to solve this problem:

public class PersonFactory {
    
    
    public static Person getPerson(){
    
    
        return new Person();
    }
}

public class Student {
    
    
    private Person person = PersonFactory.getPerson();

    public void eatForStudent(){
    
    
        person.eat();
        System.out.println("喝牛奶!");
    }
}

Then call the getPerson method in the Student class to return the Person class object, and give the process of creating the object to the factory class PersonFactory to do. If other classes also call the getPerson method in the PersonFactory class to obtain the Person class object, then if the Person's If the class path or class name is changed, only one place needs to be changed, which is to change the class name or class path in the getPerson method.

There is still a certain degree of coupling when using the factory mode. At this time, we need our IOC principle to reduce the coupling to a minimum. In this process, in addition to using the factory mode, we also need to use xml parsing and reflection. .

2. IOC principle process

Step 1: xml configuration file, configure the created object

<bean id="person" class="iocprinciple.Person"></bean>

Step 2: Create a factory class (using xml parsing and reflection to create an object of the Person class based on the factory pattern)

public class PersonFactory {
    
    
    public static Person getPerson() throws Exception {
    
    
        //Dom4j xml解析获取类的全路径
        String classPath = new ClassPathXmlApplicationContext("bean1.xml").getClassPath("person");

        //通过反射得到类的字节码文件
        Class clazz = Class.forName(classPath);

        //调用方法得到对象
        Person person = (Person)clazz.newInstance();

        return person;
    }

}

The Person class content remains unchanged, and Student becomes as follows:

public class Student {
    
    
    private Person person;
    
    public void eatForStudent(){
    
    

        try {
    
    
            person = PersonFactory.getPerson();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        person.eat();
        System.out.println("喝牛奶!");
    }
}

The XML parsing classes used in Dom4j are as follows:

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ClassPathXmlApplicationContext {
    
    
    private String configFilePath;

    public ClassPathXmlApplicationContext(String configFilePath) {
    
    
        this.configFilePath = configFilePath;
    }

    /*
     * dom4j解析
     */
    public String getClassPath(String id) throws Exception {
    
    
        String classPath = null;
        // 解析xml
        SAXReader reader = new SAXReader();
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(configFilePath);
        Document document = reader.read(inputStream);
        if (document == null) {
    
    
            return null;
        }
        // 从项目根目录下读取
        Element root = document.getRootElement();

        // 获取节点资源
        List<Element> list = root.elements();
        if (list.size() <= 0) {
    
    
            return null;
        }
        for (Element element : list) {
    
    
            String idString = element.attributeValue("id");
            if (id.equals(idString)) {
    
    
                // 获取bean的class地址
                classPath = element.attributeValue("class");
                break;
            }
        }
        return classPath;
    }

}

This is the underlying principle of IoC in spring. In the subsequent use process, we only need to write the spring xml configuration file. Spring has already written the underlying code of IoC for us.

Guess you like

Origin blog.csdn.net/MrYushiwen/article/details/109953263