Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

Dependency Injection (DI)

Dependency injection (DI) is a process by which an object can define its dependencies (that is, other objects that work with them) only through constructor parameters, factory method parameters, or properties that are set on the object instance after it is constructed or created. Return from the factory method. The container then injects those dependencies when the bean is created. Essentially, this process is a reverse process (hence Control Inversion) of the Bean itself that controls the instantiation or location of its dependencies by using either the direct construction of the class or the service locator pattern.

Using the DI principle, the code is cleaner, and decoupling is more effective when providing dependencies to objects. The object does not look up its dependencies and does not know the location or class of the dependencies. As a result, your classes become easier to test, especially when dependencies depend on interfaces or abstract Base classes, which allow stub or mock implementations to be used in unit tests.

There are two main variants of DI: constructor-based dependency injection and setter-based dependency injection.

Constructor injection

1. Create object with no-parameter construct (default)

  public User(a) {}Copy the code

2. Create an object with a parameter construct

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
Copy the code
  • 1. Constructor parameter subscript index (starting from 0)

    You can explicitly specify the index of a constructor parameter using the index attribute

    <bean id="user" class="com.cheng.pojo.User">
        <constructor-arg index="0" value="spring"></constructor-arg>
        <constructor-arg index="1" value="3"></constructor-arg>
    </bean>
    Copy the code
  • 2. Constructor parameter types match

    When the type of the constructor argument is explicitly specified using the type attribute, the container can use type matching of simple types. This parameter is not recommended when there are two parameters of the same type.

    <bean id="user" class="com.cheng.pojo.User">
        <constructor-arg type="java.lang.String" value="spring"></constructor-arg>
        <constructor-arg type="int" value="3"></constructor-arg>
    </bean>
    Copy the code
  • 3. Constructor parameter names

    Constructor parameter names can be used to disambiguate:

    <bean id="user" class="com.cheng.pojo.User">
        <constructor-arg name="name" value="spring"/>
        <constructor-arg name="age" value="3"/>
    </bean>
    Copy the code

2. Set injection mode (common)

  • Dependency injection: Set injection
    • Dependencies: The creation of bean objects depends on the container
    • Injection: All properties in the bean object are injected by the container

Environment set up

  • 1. Complex types

    package com.cheng.pojo;
    
    public class Address {
        private String address;
    
        public String getAddress(a) {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
        @Override
        public String toString(a) {
            return "Address{" +
                    "address='" + address + '\' ' +
                    '} '; }}Copy the code
    package com.cheng.pojo;
    
    import java.util.*;
    
    public class Student {
        private  String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Map<String,String> card;
        private Set<String> games;
        private String wife;
        private Properties info;
    
        public String getName(a) {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Address getAddress(a) {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public String[] getBooks() {
            return books;
        }
    
        public void setBooks(String[] books) {
            this.books = books;
        }
    
        public List<String> getHobbys(a) {
            return hobbys;
        }
    
        public void setHobbys(List<String> hobbys) {
            this.hobbys = hobbys;
        }
    
        public Map<String, String> getCard(a) {
            return card;
        }
    
        public void setCard(Map<String, String> card) {
            this.card = card;
        }
    
        public Set<String> getGames(a) {
            return games;
        }
    
        public void setGames(Set<String> games) {
            this.games = games;
        }
    
        public String getWife(a) {
            return wife;
        }
    
        public void setWife(String wife) {
            this.wife = wife;
        }
    
        public Properties getInfo(a) {
            return info;
        }
    
        public void setInfo(Properties info) {
            this.info = info;
        }
    
        @Override
        public String toString(a) {
            return "Student{" +
                    "name='" + name + '\' ' +
                    ", address=" + address.toString() +
                    ", books=" + Arrays.toString(books) +
                    ", hobbys=" + hobbys +
                    ", card=" + card +
                    ", games=" + games +
                    ", wife='" + wife + '\' ' +
                    ", info=" + info +
                    '} '; }}Copy the code
  • 2. Real test object

    // Implement the injection of all the following attributes
    private  String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;
    Copy the code
  • 3.applicationContext.xml

    
            
    <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="address" class="com.cheng.pojo.Address"></bean>
    
        <bean id="student" class="com.cheng.pojo.Student">
            <! Insert a value into a normal value with value-->
            <property name="name" value="Thousands of miles"/>
            <! -- bean injection, ref-->
            <property name="address" ref="address"/>
            <! -- Array injection -->
            <property name="books" >
                <array>
                    <value>Journey to the west</value>
                    <value>A dream of red mansions</value>
                    <value>Water margin</value>
                    <value>The romance of The Three Kingdoms</value>
                </array>
            </property>
            <! Select * from List;
            <property name="hobbys">
                <list>
                    <value>Play the game</value>
                    <value>See a movie</value>
                    <value>Knock on the code</value>
                </list>
            </property>
            <! -- Map injection -->
            <property name="card">
                <map>
                    <entry key="Name" value="Thousands of miles"/>
                    <entry key="Department don't" value=Department of Information Engineering/>
                    <entry key="Grade" value="18"/>
                    <entry key="Professional" value="Computer Science and Technology"/>
                </map>
            </property>
            <! -- Set injection -->
            <property name="games">
                <set>
                    <value>LOL</value>
                    <value>COC</value>
                    <value>BOB</value>
                </set>
            </property>
            <! -- Null injection -->
            <property name="wife">
                <null/>  <! -- equivalent to student.setwife (null); -->
            </property>
    <! --<property name="wife" value=""> equivalent to student.setwife (""); Set the wife property to an empty string value -->
    
            <! Insert properties into properties
            <property name="info">
                <props>
                    <prop key="Student id">08090335615</prop>
                    <prop key="Name">Wan Li</prop>
                </props>
            </property>
        </bean>
    </beans>
    Copy the code
  • 4. The test class

    import com.cheng.pojo.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            Student student = (Student) context.getBean("student"); System.out.println(student.toString()); }}Copy the code

    Test results:

    Student{name='away', address=Address{address='null'}, books= journey to the West, dream of the Red Chamber, Water Margin, romance of The Three Kingdoms, hobbys=, card={name = wanli, department = Department of Information Engineering, grade =18Level, pro = Computer Science & Technology}, games=[LOL, COC, BOB], wife='null', info={student id =08090335615, name = wanli}}Copy the code

3. Injection of expansion methods

P namespace injection and C namespace injection cannot be used directly. Import constraints are required

Injection p namespace XMLNS: p = “www.springframework.org/schema/p”

Injection c namespace XMLNS: c = “www.springframework.org/schema/c”

1. Environment construction

package com.cheng.pojo;

public class User {
    private String name;
    private int age;
    private Address address;

    public User(a) {}public String getName(a) {
        return name;
    }

    public User(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge(a) {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress(a) {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString(a) {
        return "User{" +
                "name='" + name + '\' ' +
                ", age=" + age +
                ", address=" + address +
                '} '; }}Copy the code

2.userbeans.xml

  • P namespace injection

    
            
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <! --p namespace injection, can inject the value of the attribute directly, can also inject a reference -->
        <bean id="user" class="com.cheng.pojo.User"
              p:name="Thousands of miles"
              p:age="3"
              p:address-ref="address"/>
    </beans>
    Copy the code
  • C Namespace injection

    
            
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:c="http://www.springframework.org/schema/c"
           xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <! --c namespace injection, via constructor injection, construct-org -->
        <bean id="user2" class="com.cheng.pojo.User" c:name="Thousands of miles" c:age="3" c:address-ref="address"/>
    </beans>
    Copy the code

The test class

    @Test
    public void test(a){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user2", User.class);// Use reflection instead of type force
        System.out.println(user);
}
Copy the code