What is Spring's IoC and how to implement dependency injection?

Follow the "Java Architecture Stack" WeChat official account and reply with the password [Java Interview Questions] to get the interview questions from big companies

 What is IoC

The so-called Inversion of Control, abbreviated as IoC, is actually a technology that leaves the creation of objects and the dependency processing between objects to the Spring container for management, without the need for programmers to create and maintain them themselves. Our purpose of using IoC is mainly to reduce the coupling between classes.

 The underlying principles of IoC

The underlying principle of IoC is mainly implemented based on technologies such as xml parsing + factory mode + reflection.

  • xml parsing: Based on xml, configure the Javabean object to be created;

  • Factory pattern: All work such as creation and initialization of classes is handed over to a factory for execution;

  • Reflection: Use reflection technology to create beans configured in xml.

 IoC simulation implementation

In order to let everyone better understand the working principle of IoC, let's briefly simulate the underlying implementation principle of Spring IoC.

The first step: We first prepare a properties file beans.properties. I use the properties file here instead of the xml file function.

dept=com.qfedu.pojo.Dept
emp=com.qfedu.pojo.Emp

Step 2: Write the factory class QfBeanFactory.java

/**
* 模拟spring 容器的工厂类
*/
public class QfBeanFactory {
    private static Properties properties = new Properties();
    //该map相当于spring容器,用来存储创建好的bean对象
    private static Map<String, Object> ioc = new HashMap<String, Object>();
    static {
        try {
            properties.load(BeanFactory.class.getClassLoader().getResourceAsStream("beans.properties"));
            //获取所有属性名
            Set<String> names = properties.stringPropertyNames();
            System.out.println(names);
            //通过反射技术创建属性文件里配置的要创建的bean开始
            for (String name : names) {
                //获取全类名
                String clsName= (String) properties.get(name);
                Class clazz=Class.forName(clsName);
                if (!Objects.isNull(clazz)){
                    //反射构建对象
                   Object object=clazz.getConstructor().newInstance();
                   // 存储到map中
                   ioc.put(name,object);
                }
            }
         //通过反射技术创建属性文件里配置的要创建的bean结束
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
       通过属性文件中属性名(类似spring配置文件中的bean的id)获取工厂创建好的对象
    */
    public  static Object getBean(String beanName){
        return ioc.get(beanName);
    }
}

Code explanation:

  • The static code block in the factory class implements reading the configuration information in the property file;

  • Based on the read configuration information, use reflection technology to construct the bean object;

  • Then put the constructed object into the map;

  • Obtain the bean object created in the factory through the provided getBean method.

Step 3: Let’s write another test class:

public class IocTest{
  public static void main(String[] args) {
      Dept dept= (Dept)QfBeanFactory.getBean("dept");
      System.out.println(dept);
      Emp emp= (Emp)QfBeanFactory.getBean("emp");
      System.out.println(emp);
    }
}

After the above test, we can get the created dept and emp objects. Above we simulated the principle of spring ioc.

 Creation of bean objects

Next, let's take a look at how the Spring framework creates and uses bean objects.

4.1 Create spring-bean.xml configuration file

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dept" class="com.qfedu.pojo.Dept"></bean>

    <bean id="emp" class="com.qfedu.pojo.Emp"></bean>

</beans>

4.2 Load the configuration file to obtain the Spring IoC container

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-bean.xml");

4.3 Obtain dept and emp objects through spring container

Emp emp= (Emp) applicationContext.getBean("emp");
System.out.println(emp);
Dept dept= (Dept) applicationContext.getBean("dept");
System.out.println(dept);

4.4 Summary

Finally, let's summarize the process of creating bean objects in Spring.

  • spring-bean.xml is equivalent to

    beans.properties;

  • ClassPathXmlApplicationContext is equivalent to QfBeanFactory;

  • The getBean method is equivalent to getBean in QfBeanFactory.

The structure diagram of the ClassPathXmlApplicationContext class is as follows:

From the above class structure diagram, we can see that the top level of ClassPathXmlApplicationContext is the BeanFacorty factory, and ClassPathXmlApplicationContext is a specific implementation class. BeanFacorty has many implementation classes, among which ClassPathXmlApplicationContext and AnnotationConfigApplicationContext are more commonly used specific subclasses.

BeanFactory ends with Factory, indicating that this is a factory class (interface), which is responsible for producing and managing a factory of beans. In Spring, BeanFactory is the core interface of the IOC container. Its responsibilities include instantiating, locating, configuring objects in the application, and establishing dependencies between these objects. BeanFactory is just an interface, not a specific implementation of the IoC container, so the Spring container provides multiple implementations, such as ClassPathXmlApplicationContext, AnnotationConfigApplicationContext, ApplicationContext, etc.

Now do you know how Spring implements IoC? If you still have any questions, you can leave a message in the comment area. Pay attention to the Java architecture stack, and there will be lots of useful information every day!

Guess you like

Origin blog.csdn.net/weixin_41692221/article/details/131434907