Spring IoC container and Bean management 19: scope and life cycle of Bean objects 4: implement a simple IoC container; (this blog is for reference only)

Posted by zz50 on Mon, 27 Dec 2021 18:06:02 +0100

explain:

(1) The purpose of this blog is to help deepen the understanding of Spring IoC container, mainly to understand how to use reflection mechanism to create objects and inject data behind Spring IoC container;
(2) The content in this blog does not need to be remembered, but is only used to improve the understanding of Spring IoC container;

(3) Through the introduction of this blog, we can feel that the principle of IoC container is not complex; the essence of IoC container is a Map key value pair object;

(4) This blog is only the basic implementation of IoC container; the IoC container in Spring framework is much more complex than that in this blog;

catalogue

0. To demonstrate, create a maven project: s07

1. Create an Apple class:

2. Create ApplicationContext XML configuration file

3. Create ApplicationContext interface and ClassPathXmlApplicationContext implementation class

4. Create a SpringApplication class to test

0. To demonstrate, create a maven project: s07

1. Create an Apple class:

Apple class:

package com.imooc.spring.ioc.entity;

import javax.print.attribute.standard.RequestingUserName;

public class Apple {
    private String title;
    private String color;
    private String origin;

    public Apple() {
    }

    public Apple(String title, String color, String origin) {
        this.title = title;
        this.color = color;
        this.origin = origin;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getColor() {
        return color;
    }

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

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String origin) {
        this.origin = origin;
    }
}

explain:

(1) This Apple class has nothing to say, an ordinary javaBean;

Then, we create a configuration file, and then write the information of an Apple object in the configuration file according to the rules and styles of Spring IoC;

2. Create ApplicationContext XML configuration file

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="Red Fuji"/>
        <property name="color" value="gules"/>
        <property name="origin" value="Europe"/>
    </bean>
</beans>

Description:

(1) The name of this configuration file can be given freely. It is simply the same as Spring IoC, also called applicationContext.xml;

(2) In this applicationContext.xml, the information of an Apple object is written according to the rules and styles of the Spring IoC configuration file;

After the configuration file is written, how to create objects for the configuration file at runtime? We need to implement the IoC container ourselves; Next, according to the rules and styles of Spring IoC, load the xml configuration file and complete the initialization of IoC container;

3. Create ApplicationContext interface and ClassPathXmlApplicationContext implementation class

ApplicationContext interface:

package com.imooc.spring.ioc.context;

/**
 * This interface simulates the ApplicationContext interface in Spring;
 */
public interface ApplicationContext {
    public Object getBean(String beanId);
}

explain:

(1) Simulate the Spring IoC container and create a getBean() method in the ApplicationContext interface;

............................................................

ClassPathXmlApplicationContext implementation class:

package com.imooc.spring.ioc.context;

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

import java.io.File;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * This class simulates the ClassPathXmlApplicationContext class in Spring;
 * The functions of this class: (1) implement the ApplicationContext interface; (2) complete the creation process of IoC container;
 */
public class ClassPathXmlApplicationContext implements ApplicationContext{
    private Map iocContainer = new HashMap();
    public ClassPathXmlApplicationContext(){
        try{
            String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
            filePath = new URLDecoder().decode(filePath, "UTF-8");
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File(filePath));
            List<Node> beans = document.getRootElement().selectNodes("bean");
            for (Node node : beans) {
                Element element = (Element) node;
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");
                Class c = Class.forName(className);
                Object obj = c.newInstance();
                List<Node> properties = element.selectNodes("property");
                for (Node p : properties) {
                    Element property = (Element) p;
                    String propName = property.attributeValue("name");
                    String propValue = property.attributeValue("value");
                    String setMethodName = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
                    Method setMethod = c.getMethod(setMethodName, String.class);
                    setMethod.invoke(obj, propValue);//Inject data through setter method
                }
                iocContainer.put(id, obj);
            }
            System.out.println("IoC Container initialization completed.");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public Object getBean(String beanId) {
        return iocContainer.get(beanId);
    }
}

explain:

(1) The responsibility of this class is to implement the ApplicationContext interface and complete the creation process of IoC container. It can be understood that each ClassPathXmlApplicationContext object corresponds to an IoC container, which is used to store objects;

(2) In Java, IoC container uses Map to save objects. key corresponds to beanId and value corresponds to corresponding objects;

(3) In the process of instantiating the ClassPathXmlApplicationContext object, the applicationContext.xml configuration file is loaded and processed, so the main code is written in the default construction method of ClassPathXmlApplicationContext. At the same time, because exceptions may occur in this process, it is written in the try block;

(4) Obtain the address of the configuration file applicationContext.xml;

I've met the content here N times before. For example, the first time I met it was in[ Foreground system 2: demand analysis and data modeling: create data tool class and paging tool class; Dao data object access class; (Dao part of Model of paging module) ], if necessary, you can quickly refer to this blog;

(5) After obtaining the address of the applicationContext.xml file, the file is parsed; since the file is an XML file, the existing wheels can be used to improve the efficiency of the program; dom4j and jaxen are introduced;

Dom4j: it is an xml parsing component of java, which can convert xml files into a document object to help us read and manipulate xml content; Jaxen: when using Dom4j and XPath query, you must first download jaxen's jar package; When querying xml files quickly, you need to introduce jaxen, which is the Dom4j underlying dependency; This part can be referred to quickly if necessary[ XML 3: how to use Java to manipulate XML? DOM; Introduction to Dom4j; The project imports Dom4j this jar package ]And relevant articles nearby;

(6) Parsing xml files: this part can be referred to quickly if necessary[ XML 3: how to use Java to manipulate XML? DOM; Introduction to Dom4j; The project imports Dom4j this jar package ]And relevant articles nearby;

For reflection technology, you can refer to it quickly if necessary[ Java reflection 1: Reflection Introduction (a case, perceptual knowledge of what reflection is); (. class,Class.forName() and getClass() (difference) ]And relevant articles nearby;

 

So far, the initialization code of the IoC container has been written;

4. Create a SpringApplication class to test

SpringApplication class:

package com.imooc.spring.ioc;

import com.imooc.spring.ioc.context.ApplicationContext;
import com.imooc.spring.ioc.context.ClassPathXmlApplicationContext;
import com.imooc.spring.ioc.entity.Apple;

public class SpringApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext();
        Apple sweetApple = (Apple) context.getBean("sweetApple");
        System.out.println(sweetApple);
    }
}

Operation results:

............................................................

Make a breakpoint here to further observe: