[Spring practice series] (7) constructor injection in Spring injection mode
1. constructor Injection
Constructor-based injection is implemented by calling the constructor with parameters. Each parameter represents a co-author.
1.1 simplest form
The following example describes the Student object class:
package com.sjf.bean;
/**
* Student Entity
* @author sjf0115
*
*/
public class Student {
private String name;
private String company;
private int age;
private boolean sex;
public Student(String name, String company, int age, boolean sex) {
this.name = name;
this.company = company;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
StringBuilder. append ("personality details:" + "\ n ");
stringBuilder.append("name:" + name + "\n");
stringBuilder.append("company:" + company + "\n");
stringBuilder.append("age:" + age + "\n");
stringBuilder.append("sex:" + (sex ? "boy" : "girl"));
return stringBuilder.toString();
}
}
The Student class has four attributes: name, company, age, and sex. These four attributes are set through constructor injection. Override the toString () method of Student to display the Student object information.
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">
Running result:
name:yoona
company:Facebook
age:24
sex:true
1.2 pass the value based on the type attribute
The constructor-arg element in bean is used to set attributes through constructor injection. Because the Student class has only one constructor, the Code has no problems. Conflict occurs when there are constructors of the same number. Consider the following:
We provide Student classTwo constructors:
public Student(String name, String company) {
this.name = name;
this.company = company;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
Configuration file:
Which constructor do you think will be called now? According to our thinking, it should be the second constructor with String and int parameters. Is it true? In fact, Spring will call the first constructor. Even if we know that the first parameter is String and the second parameter is int, Spring parses all the parameters into String.
Running result:
name:yoona
company:24
In this case, we can use the type attribute in the Parameter definition of the constructor to explicitly specify the simple type corresponding to the parameter. The second constructor will be called as follows:
After this setting, value = "24" is of the int type and is not considered as a String. Therefore, it can only match the publicStudent (String name, int age) constructor.
Running result:
name:yoona
age:24
1.3 pass the value based on the index attribute
You can use the index attribute to explicitly specify the sequence in which the constructor parameters appear. Specifying the index of the constructor parameter is the preferred method to use the constructor IoC.
Consider the following situations. We have the following in the Student class:Constructor:
public Student( int age, String company) {
this.company = company;
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
Configure as follows:
Which constructor do you think will be called now? Second? However, the first constructor is actually called. In the call constructor, the parameter sequence defined in the configuration file is not sequential.
Running result:
company:yoona
age:24
To solve this problem, you must specify the index attribute. The configuration is as follows:
After this setting, value = "yoona" must correspond to the first parameter in the constructor, so it can only match the publicStudent (String name, int age) constructor.
Running result:
name:yoona
age:24
1.4 pass the value based on the name attribute
There is also a recommended method: Matching Based on the name attribute. For the above constructor, we use the name attribute to configure the following:
After this configuration, value = "yoona" can only correspond to the name attribute, and value = "24" can only correspond to the age attribute.
Running result:
name:yoona
age:24
1.5 inject object reference through the constructor
We provide Student with a school entity class:
package com.sjf.bean;
/**
* School entity
* @author sjf0115
*
*/
public class School {
private String name;
private String location;
public School(String name, String location) {
this.name = name;
this.location = location;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("name:" + name);
stringBuilder.append(" location:" + location);
return stringBuilder.toString();
}
}
We use the constructor injection method to configure the School class:
package com.sjf.bean;
/**
* Student Entity
* @author sjf0115
*
*/
public class Student {
private String name;
private School school;
private int age;
public Student(String name, School school, int age) {
this.name = name;
this.school = school;
this.age = age;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
StringBuilder. append ("personal details:" + "\ n ");
stringBuilder.append("name:" + name + "\n");
stringBuilder.append("age:" + age + "\n");
stringBuilder.append("school:" + school.toString());
return stringBuilder.toString();
}
}
Configure Student:
Here we cannot use the value attribute to assign values to the second constructor, because School is not a simple type. Instead, we use the ref attribute to pass the Bean reference with ID xidian to the constructor.