Spring's core mechanism -- dependency injection

Posted by orange08 on Sat, 20 Nov 2021 03:23:33 +0100

catalogue

Concept of dependency injection

First, create a common class

Modify the TestHello class again

Modify profile

Writing test classes

Operation results

  analysis

  Two ways of dependency injection

set injection

Structural injection

  Operation results

  Comparison of two injection methods

Concept of dependency injection

The core mechanism of Spring is dependency injection (DI), also known as inversion of control (IOC).

This article continues from the previous one Introduction to Spring development

First, create a common class

package org.example;

public class TestDao {
    public String test(){
        return "I don't know what to do?";
    }
}

Modify the TestHello class again

package org.example;

public class TestHello {
    private TestDao testDao;

    //Must have
    public void setTestDao(TestDao testDao) {
        this.testDao = testDao;
    }
    public void testHello(){
        System.out.println(testDao.test());
    }

}

Modify profile

Modify the applicationContext.xml 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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="TestHello" class="org.example.TestHello">
        <!--property Element is used to specify the attributes that need container injection. Here is set value injection, so TestHello Class must have setTestDao method-->
        <property name="TestDao">
            <!--Another one will be here bean Reference injection to TestHello bean-->
            <ref bean="TestDao"></ref>
        </property>

    </bean>
    <bean id="TestDao" class="org.example.TestDao">

    </bean>
</beans>

Writing test classes

package org.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main( String[] args ) {
        //Get ApplicationContext object
        ApplicationContext application=new ClassPathXmlApplicationContext("ApplicationContext.xml");
        //Get TestHello object through ApplicationContext
        //The parameter in the getBean () method is the value of the Bean id in the configuration file
        TestHello testHello=(TestHello) application.getBean("TestHello");
        testHello.testHello();
    }
}

Operation results

  analysis

Normally, we need to call the methods in TestDao through

//Create TestHello real column
TestDao testDao=new TestDao();
//Call method
testDao.test();

However, in the above program, there is no TestHello instance and TestDao instance coupled together. That is, the program does not create a new TestDao instance in the TestHello instance. The TestDao instance is dynamically "injected" into the TestHello instance by Spring during runtime. When the program runs to the point where it needs a TestDao instance, Spring creates it and injects it into the caller who needs it. When the TestHello instance runs where the TestDao instance is needed, TestDao is naturally generated for its use. This way of generating instances is called dependency injection. It can be found that when TestDao is applied in TestHello, the setter method of its instance is generated, and Spring creates an instance of TestDao through this setter method.

  Two ways of dependency injection

set injection

set injection is described above, and structure injection is described below.

Structural injection

Construction injection refers to defining a construction method in the injected class and defining the elements to be injected in the parameters of the construction method.

Continue with the above example. First, modify the TestHello.java class and add a constructor to the class

package org.example;

public class TestHello {
    private String message;

    //Construction method
    public TestHello(String message) {
        this.message = message;//Structural injection
    }

    public String getMessage() {
        return message;
    }
}

Modify the ApplicationContext.xml file

Constructor Arg: indicates that dependency injection is carried out through construction;
index=0: indicates the first parameter in the construction method, which can be omitted. If there are multiple parameters, simply configure constructor Arg repeatedly, but change the value of index. For example, if there is also a parameter sex in the TestHello class, and the value is injected into it through the construction method:
    public TestHello(String message,String sex) {
        this.message = message;//Structural injection
        this.sex=sex;
    }

Then you need to add a constructor Arg to the configuration file ApplicationContext.xml

    <bean id="TestHello" class="org.example.TestHello">
        <constructor-arg index="0">
            <value>I know what I'm doing! Learning, of course!</value>
        </constructor-arg>
        <constructor-arg index="1">
            <value>female</value>
        </constructor-arg>
    </bean>

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="TestHello" class="org.example.TestHello">
        <constructor-arg index="0">
            <value>I know what I'm doing! Learning, of course!</value>
        </constructor-arg>
    </bean>
</beans>

  Operation results

  Comparison of two injection methods

Using construction injection can complete the establishment of dependencies while building objects. Therefore, if there are many relationships of objects to be established, using construction injection will leave many parameters on the construction method, and the method readability is poor. It is recommended to use set injection. However, with set injection, because the setXX() method is provided, it can not guarantee that the relevant data will not be changed during execution. Therefore, if you want to make some data read-only or private, using construct injection will be a good choice.

Topics: Java Maven Spring