Spring ----------- DI based on XML

Posted by mrneilrobinson on Fri, 04 Feb 2022 11:11:16 +0100

1, Injection classification

After the bean instance calls the parameterless constructor to create the object, it needs to initialize the properties of the bean object. Initialization is done automatically by the container, which is called injection. According to different injection methods, there are two common types: set injection and structure injection.

2, set injection

Set injection, also known as set value injection, refers to the instance passed into the callee through the setter method. This injection method is simple and intuitive, so it is widely used in Spring dependency injection.

(1) Simple type

Define student classes

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
     @Override
    public String toString() {
        return "name : " + name + " | age : " + age;
    }
}

In ApplicationContext Create a student object in the XML file and assign its attributes (i.e. injection)

Using < property > in the < bean > tag can complete the assignment of object properties through key value pairs

<bean id="myStudent" class="com.fancy.Student">
     <property name="age" value="18"></property>
     <property name="name" value="zhang"></property>
</bean>

Define test method

 public void test01() {
        // 1. Specify the location and name of the spring configuration file
        String resource = "applicationContext.xml";
        // 2. Create spring container object
        ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
        // 3. Get the object from the spring container and use id
        Student student = (Student) ac.getBean("myStudent");
        // 4. Business method of execution object
        System.out.println(student);
}

Create Java util. Date object and set the initial date time

<bean id="myDate" class="java.util.Date">
      <property name="time" value="1000000"></property>
</bean>

Define test class

 @Test
    public void test01() {
        // 1. Specify the location and name of the spring configuration file
        String resource = "applicationContext.xml";
        // 2. Create spring container object
        ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
        // 3. Get the object from the spring container and use id
       Date date = (Date) ac.getBean("myDate");
        // 4. Business method of execution object
        System.out.println(date);
    }

(2) Reference type

When a property value of a specified bean is an instance of another bean, the reference relationship between them is specified through Ref. The value of ref must be the id value of a bean.

Define school and student categories

package com.fancy;

public class School {
    private String name;
    private String address;

    public School() {
    }

    public School(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

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

package com.fancy;

public class Student {
    private String name;
    private int age;
    private School school;
    public Student() {
    }

    public Student(String name, int age, School school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    @Override
    public String toString() {
        return "name : " + name + " | age : " + age + " | schoolName : " + school.getName() + " | schoolAddress : " + school.getAddress();
    }
}

Declare a School type object

<bean id="mySchool" class="com.fancy.School">
        <property name="name" value="QDU"></property>
        <property name="address" value="Qingdao"></property>
</bean>

For references to other Bean objects, use the ref attribute of the < Bean / > tag

 <bean id="myStudent" class="com.fancy.Student">
          <property name="age" value="18"></property>
          <property name="name" value="zhang"></property>
          <property name="school" ref="mySchool"></property>
 </bean>

test method

	 @Test
	 public void test01() {
	    // 1. Specify the location and name of the spring configuration file
	    String resource = "applicationContext.xml";
	    // 2. Create spring container object
	    ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
	    // 3. Get the object from the spring container and use id
	    Student student = (Student) ac.getBean("myStudent");
	    // 4. Business method of execution object
	    System.out.println(student);
	}

3, Structural injection

Construction injection refers to completing the instantiation of the callee while constructing the caller instance. That is, use the constructor to set dependencies.

(1) Custom type construction injection

First, write the parametric construction method in the class

public Student(String name, int age, School school) {
      this.name = name;
      this.age = age;
      this.school = school;
}

For construction injection, you need to use the < constructor Arg / > tag in < bean / >

<bean id="myStudent" class="com.fancy.Student">
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="name" value="zhang"></constructor-arg>
        <constructor-arg name="school" ref="mySchool"></constructor-arg>
 </bean>

The attributes used to specify parameters in the < constructor Arg / > tag are:
 Name: Specifies the parameter name.
 index: indicates that the parameter corresponds to the first parameter of the constructor, starting from 0. However, this attribute should not be used, but it should be noted that if the parameter types are the same or there is a containment relationship between them, it is necessary to ensure that the assignment order is consistent with the parameter order in the constructor.

(2) Create a system class File object using construct injection

<bean id="myFile" class="java.io.File">
        <!--Create a File object, express pom.xml-->
        <constructor-arg name="parent" value="F:\Spring\IoC Control reversal"></constructor-arg>
        <constructor-arg name="child" value="pom.xml"></constructor-arg>
        <!-- parent Used to indicate the absolute path of the directory where the file is located child Indicates the file name-->
 </bean>

test method

  @Test
  public void test01() {
        // 1. Specify the location and name of the spring configuration file
        String resource = "applicationContext.xml";
        // 2. Create spring container object
        ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
        // 3. Get the object from the spring container and use id
        File file = (File) ac.getBean("myFile");
        // 4. Business method of execution object
        System.out.println("File path : " + file.getAbsolutePath());
        System.out.println("File name : " + file.getName());
 }

4, Automatic injection

For the injection of reference type attributes, you can also not display the injection in the configuration file. You can implicitly auto inject the reference type attribute by setting the autowire attribute value for the < bean / > tag (the default is not to automatically inject the reference type attribute). According to the different judgment criteria of automatic injection, it can be divided into two types:

  • byName mode automatic injection
  • byType mode automatic injection

(1) byName mode automatic injection

When the id value of the caller bean in the configuration file is in line with the attribute name of the caller bean class in the code, the byName can be used to allow the container to automatically inject caller bean to the caller bean. The container is automatically injected by comparing the attribute name of the caller's bean class with the id of the callee's bean in the configuration file.

Still take the student class as an example

We create a school object with id school in the configuration file

 <bean id="myStudent" class="com.fancy.Student" autowire="byName">
              <property name="age" value="18"></property>
              <property name="name" value="zhang"></property>
<!--              <property name="school" ref="mySchool"></property>-->
       </bean>
       <bean id="school" class="com.fancy.School">
              <property name="name" value="QDU"></property>
              <property name="address" value="Qingdao"></property>
       </bean>


The output result is the same as above

(2) byType mode automatic injection

Automatic injection in byType mode requires that the class specified by the class attribute of the caller bean in the configuration file should be the same as the reference type attribute type of the bean class in the code. That is, it is either the same or has an is-a relationship (subclass or implementation class). However, there can only be one such homologous called bean. If there is more than one, the container does not know which one to match.


Unlike byName, byType requires that the two class es be associated

<bean id="myStudent" class="com.fancy.Student" autowire="byType">
        <property name="age" value="18"></property>
        <property name="name" value="zhang"></property>
<!--    <property name="school" ref="mySchool"></property>-->
</bean>
<bean id="mySchool" class="com.fancy.School">
        <property name="name" value="QDU"></property>
        <property name="address" value="Qingdao"></property>
</bean>

5, Specify multiple Spring configuration files for the application

In practical application, with the increase of application scale, the number of beans in the system also increases greatly, resulting in the configuration file becoming very large and bloated. In order to avoid this situation and improve the readability and maintainability of the configuration file, the Spring configuration file can be decomposed into multiple configuration files.

Profiles containing relationships:

There is a general file in multiple configuration files, which introduces other sub files through < import / >. In Java code, you only need to initialize the container with the general configuration file.

For example: previously, we put Student type objects and School type objects in the same configuration file. Now we put them into two separate configuration files and integrate them into total XML is the general configuration file

That is, use < import / > to import two configuration files

 <import resource="classpath:spring-school.xml"></import>
 <import resource="classpath:spring-student.xml"></import>

Wildcards * can also be used. However, at this time, it is required that the parent configuration file name cannot meet the format that * can match, otherwise circular recursive inclusion will appear. For this example, the parent profile cannot match spring - * XML format, that is, it cannot be named spring total xml.

<import resource="classpath:spring-*"></import>

Topics: Java Spring xml