Spring - dependency injection

1. Concept

The so-called dependency injection (DI) actually means that when a bean instance references another bean instance, the spring container helps us create a dependent bean instance and inject (pass) it into another bean.

  • Dependency: the creation of a Bean object depends on the container, and the Bean object depends on resources
  • Injection: refers to the resources that the Bean object depends on, which are set and assembled by the container

2. Constructor injection

That is, the IOC object creation method in Hello spring.

3. set injection

As the name suggests, set injection requires a set method for the injected property. Set injection supports simple types and reference types. Setter injection is executed after the bean instance is created.

  1. Address entity class
public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}
  1. Student entity class
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Map<String, String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        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> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbies=" + hobbies +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}
  1. injection
<bean id="address" class="com.xbaozi.pojo.Address">
    <property name="address" value="localhost"/>
</bean>
<bean id="student" class="com.xbaozi.pojo.Student">
    <!-- Constant injection -->
    <property name="name" value="Spring"/>
    <!-- Bean Injection, through ref And another bean of id introduce bean -->
    <property name="address" ref="address"/>
    <!-- Array injection -->
    <property name="books">
        <array>
            <value>The Dream of Red Mansion</value>
            <value>Journey to the West</value>
            <value>Water Margin</value>
            <value>Romance of the Three Kingdoms</value>
        </array>
    </property>
    <!-- List injection -->
    <property name="hobbies">
        <list>
            <value>Engage in peripherals</value>
            <value>Knock code</value>
            <value>change bug</value>
            <value>Wear a wig</value>
        </list>
    </property>
    <!-- Map injection -->
    <property name="card">
        <map>
            <entry key="Student number" value="20220987612"/>
            <entry key="Professional number" value="0987"/>
        </map>
    </property>
    <!-- Set injection -->
    <property name="games">
        <set>
            <value>LOL</value>
            <value>GTA</value>
            <value>DOTA</value>
        </set>
    </property>
    <!-- Null injection -->
    <property name="wife">
        <null/>
    </property>
    <!-- Properties injection -->
    <property name="info">
        <props>
            <prop key="Driver">com.mysql.jdbc.Driver</prop>
            <prop key="url">jdbc:mysql://localhost/database</prop>
            <prop key="username">root</prop>
            <prop key="password">123456</prop>
        </props>
    </property>
</bean>
  1. test
@Test
public void test01() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) context.getBean("student");
    System.out.println(student);
}

------- The test result is too long cv Come out and put it under --------
    
/* From top to bottom
    Constant injection
    bean injection
    Array injection
    List injection
    Map injection
    Set injection
    Null injection
    Properties injection
*/
Student{
    name='Spring', 
    address=Address{
        address='localhost'
    }, 
    books=[The Dream of Red Mansion, Journey to the West, Water Margin, Romance of the Three Kingdoms], 
    hobbies=[Engage in peripherals, Knock code, change bug, Wear a wig], 
    card={
        Student number=20220987612, 
        Professional number=0987
    }, 
    games=[LOL, GTA, DOTA], 
    wife='null', 
    info={
        password=123456, 
        url=jdbc:mysql://localhost/database, 
        Driver=com.mysql.jdbc.Driver, 
        username=root
    }
}

4. Other injection

In addition to the above injection methods, there are also p named injection and c named injection.

  1. User entity class
public class User {
    private String name;
    private int age;

    public User() {

    }

    public User(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 "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  1. P namespace injection: the corresponding constraint file needs to be added to the header file, that is, line 4 in the following code. To use p namespace injection, a parameterless construct must exist, otherwise an error will be reported
<?xml version="1.0" encoding="UTF-8"?>
<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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--P(attribute: properties)Namespace , Property should still be set set method-->
    <bean id="user" class="com.xbaozi.pojo.User" p:age="18" p:name="Spring"/>
</beans>
  1. c namespace injection: you need to add a constraint file in the header file, that is, line 4 in the following code. To use p namespace injection, a parameterless construct must exist, otherwise an error will be reported
<?xml version="1.0" encoding="UTF-8"?>
<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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--C(structure: Constructor)Namespace , Property should still be set set method-->
    <bean id="user01" class="com.xbaozi.pojo.User" c:name="Spring-c" c:age="18"/>
</beans>
  1. test
@Test
public void test01() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = context.getBean("user", User.class);
    System.out.println(user);
}

5. bean scope

In Spring, the subjects that make up the application and the objects managed by the Spring IoC container are called beans. Simply put, a bean is an object initialized, assembled and managed by the IoC container.

Among them, the request and session scopes are only used in web-based applications, and can only be used in Web-based Spring ApplicationContext environment.

5.1,Single

**Default scope in Spring** When the scope of a bean is singleton, there will only be one shared bean instance in the String IOC container, and all requests for a bean will return the same instance of the bean as long as the id matches the bean definition. Singleton is a singleton mode, which automatically creates a bean object when creating a container. It also exists whether you use it or not. The object obtained each time is the same object.

<bean id="user" class="com.xbaozi.pojo.User" scope="singleton">

When we make some marks in the parameterless constructor in our class, such as outputting a sentence, we will find that the parameterless constructor is called when the first statement is executed, and the last two addresses are the same.

@Test 
public void test03(){ 
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
    User user = (User) context.getBean("user"); 
    User user2 = (User) context.getBean("user"); 
    System.out.println(user==user2); 
}

5.2,Prototype

When the scope of a bean is prototype, it means that a bean definition corresponds to multiple object instances. A prototype scoped bean will cause a new bean instance to be created every time a request is made to the bean (inject it into another bean, or call the container's getBean() method programmatically). Prototype is a prototype type. It is not instantiated when we create the container. Instead, we create an object when we get the bean, and the object we get each time is not the same object. As a rule of thumb, you should use the prototype scope for stateful beans and the singleton scope for stateless beans.

<bean id="user01" class="com.xbaozi.pojo.User" scope="prototype">
<bean id="user02" class="com.xbaozi.pojo.User" singleton="false">

Similarly, when we make some marks in the parameterless constructor in our class, such as outputting a sentence, we will find that the parameterless constructor is not called when the first statement is executed, but executed when the bean is obtained, and the last output addresses of the two are different.

@Test 
public void test03(){ 
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
    User user = (User) context.getBean("user01"); 
    User user2 = (User) context.getBean("user02"); 
    System.out.println(user==user2); 
}

5.3,Request

When the scope of a bean is Request, it means that in an HTTP Request, a bean definition corresponds to an instance; That is, each HTTP Request will have its own bean instance, which is created according to a bean definition. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:

<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>

For each HTTP request, the Spring container will create a new loginaction bean instance according to the loginaction bean definition, and the loginaction bean instance is only valid in the current HTTP request. Therefore, you can safely change the internal state of the created instance according to the needs, while for the instances created according to the loginaction bean definition in other requests, You will not see these state changes specific to a request. When the processing of the request ends, the bean instance of the request scope will be destroyed.

5.4,Session

When the scope of a bean is Session, it means that in an HTTP Session, a bean definition corresponds to an instance. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

For an HTTP Session, the Spring container will create a new userPreferences bean instance according to the userPreferences bean definition, and the userPreferences bean is only valid in the current HTTP Session. Like the request scope, you can safely change the internal state of the created instance as needed. For instances created according to userPreferences in other HTTP sessions, you will not see these state changes specific to an HTTP Session. When the HTTP Session is finally discarded, the beans within the scope of the HTTP Session will also be discarded.

Keywords: Java Spring SSM intellij-idea

Added by nikneven on Wed, 02 Mar 2022 00:06:47 +0200