Spring Inversion of Control (IOC)

This is the 17th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

The IOC concept

  • Inversion of control, which hands over to Spring the management of object creation and calls between objects.
  • Use IOC to reduce coupling between objects.
  • Underlying principles of IOC: XML parsing, factory schema, reflection.

Now let’s talk about how to use IOC.

Spring configuration

Details are in the code’s comments.

1, alias,

<! -- alias (alias for user), if we have an alias, we can also get this object by alias -->
    <alias name="user" alias="aaaa"/>
Copy the code

2. Bean configuration

The heart of the Spring Ioc container is to break beans!

Basic attributes:

<! -- id: unique identifier of bean class: fully qualified name of object: package name + type name: also alias, and name can be multiple aliases, can be separated by commas, Spaces, semicolons -->
    <bean id="user1" class="mq.pojo.User" name="user2,user3 user4;">
        <constructor-arg name="name" value="maomao"/>
    </bean>
Copy the code

Scope attributes (focus on Singleton and Prototype) :

Singleton is normally used, but for struts2 integration use Prototype in ActionBean. The Request and session attributes are largely unused.

Singleton (default) : Singleton pattern. Singleton is an instance that only exists in the Spring container

Prototype property: Multiple prototypes are marked as multi-instance objects and are created each time they are acquired and each time a new object is created

Request: In the Web environment, the object has the same life cycle as the Request, that is, the object is removed from the Spring container every time the request is processed

Session: In the Web environment, the life cycle of an object is the same as that of a session

The next blog post will cover this property in more detail.

3, the import

Generally used for team development, you can combine multiple configuration files and imports into one

Use the general configuration file when you use it

The Spring IOC container

The core of SpringIOC is the IOC container, which has two main types: BeanFactory: The basic implementation of the IOC container, which is the internal interface of Spring and is not provided for developers to use. Objects are not created when the configuration file is loaded, they are created when the object is retrieved.

ApplictionContext: a subinterface of the BeanFactory interface that provides more powerful functionality and is used by developers. Objects are created when configuration files are loaded.

ApplicationContext can be implemented in four ways:

FileSystemXmlApplicationContext: when loading the configuration file is the path of the project.

ClassPathXmlApplicationContext: according to the ClassPath when loading the configuration file location. (key)

XmlWebApplicationContext: This class is loaded when listeners are initialized in the Web environment.

Start the Spring container AnnotationConfigApplicationContext: according to the annotation. (introduction)

1. Dependency Injection (DI)

  • 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. Import the Spring-related JAR packages
<! -- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9. RELEASE</version>
</dependency>
Copy the code
  1. Writing entity classes
public class Hello {
    private String name;

    public String getName(a) {
        return name;
    }

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

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

Constructor injection

1. Create object with no parameter construction (default)
  1. Write beans.xml (emphasis), where Spring performs a series of operations

Similar to mapper.xml in Mybatis, details are commented in the code


      
<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">

<! -- Use Spring to create objects. In Spring these are called Bean type variable names = new type (); Hello hello =new Hello(); Bean = object new Hello(); Object property with id= variable name class= new is equivalent to setting a value for the property in the object -->
    <bean id="hello" class="mq.pojo.Hello">
 <! -- value: a specific value, a basic data type ref: a reference to an object created in spring -->
        <property name="name" value="spring"/>
    </bean>
</beans>
Copy the code

The test class Here using the ClassPathXmlApplicationContext loading configuration file, which is the most commonly used way.

public class MyTest {

    public static void main(String[] args) {
        // Get the spring context object, get the Spring container
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // Our objects are now managed in SpringSpring, we need to use, directly fetch
        //getBean: The argument is the bean ID in the Spring configuration file
        Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); }}Copy the code

Results:Name =spring, that is, I give the value of the name property to spring in the bean object

2. Create object with parameter construction

We need to add a parameterized method to User in the entity class

public class UserT {
   private String name;
   public UserT(String name) {
       this.name = name;
  }
   public void setName(String name) {
       this.name = name;
  }
   public void show(a){
       System.out.println("name="+ name ); }}Copy the code

There are three ways to write an XML configuration file

  • The subscript assignment

    <! Subscript assignment -->
        <bean id="user" class="mq.pojo.User">
            <constructor-arg index="0" value="maomao"/>
        </bean>
    Copy the code
  • By type

    <! Create by type, not recommended -->
        <bean id="user" class="mq.pojo.User">
           <constructor-arg type="java.lang.String" value="maomao"/>
        </bean>
    Copy the code
  • By parameter name

<! -- third, by the parameter name -->
    <bean id="user" class="mq.pojo.User">
        <constructor-arg name="name" value="maomao"/>
    </bean>
Copy the code

The test class:

    public static void main(String[] args) {
        // Get the spring context object, get the Spring container
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // Our objects are now managed in SpringSpring, we need to use, directly fetch
        //getBean: The argument is the bean ID in the Spring configuration file
        User user = (User) context.getBean("user");
        user.show();
    }
Copy the code

The results of

Summary:When the configuration file is loaded, the objects managed in the container are already initialized. This is the singleton pattern in Spring configuration, where the object is created.

  • The object for User is created by Spring
  • The attributes of the User object are set by the bean’s value

This process is called inversion of control:

Control: Who controls object creation. Traditional application objects are created under the control of the program itself. With Spring, objects are created and managed by the Spring IOC container. Inversion: instead of creating objects, the program passively receives them.

Dependency injection: is to use the set method for injection.

IOC is a programming philosophy that moves from active programming to passive reception.

We don’t need to change the code in the program at all. To achieve different operations, we only need to change the XML configuration file. The so-called loC is: objects are created, managed, and assembled by Spring!

Set injection (key)

For properties to be injected, there must be a set method. The name of the set method is capitalized by the first letter of the set + property. There are String, map, list, set, Properties, String[], entity class (Bean injection) objects, etc. If you are just starting out, please read the configuration in beans.xml

Entity class: Address class

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

Student class

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;
    @Override
    public String toString(a) {
        return "Student{" +
                "name='" + name + '\' ' +
                ", address=" + address.toString() +
                ", books=" + Arrays.toString(books) +'\n'+
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\n' +
                ", info=" + 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; }}Copy the code

Write beans. XML


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="address" class="com.mq.pojo.Address">
        <property name="address" value="Changsha"/>
    </bean>

    <bean id="student" class="com.mq.pojo.Student">
<! -- value injection -->
        <property name="name" value="Little"/>
<! -- Bean injection, ref-->
        <property name="address" ref="address"/>
<! -- Array injection -->
        <property name="books">
            <array>
                <value>The Java tutorial</value>
                <value>The data structure</value>
                <value>The C language</value>
                <value>The go</value>
            </array>
        </property>
<! -- List insert -->
        <property name="hobbys">
            <list>
                <value>Listening to music</value>
                <value>Surf the Internet</value>
                <value>Play a game</value>
                <value>To play basketball</value>
            </list>
        </property>
<! -- Map injection -->
        <property name="card">
            <map>
                <entry key="Bank card" value="123456"/>
                <entry key="Bank card 2" value="123456"/>
            </map>
        </property>
<! -- Set injection -->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>CF</value>
                <value>King glory</value>
            </set>
        </property>
<! -- null value injection -->
        <property name="wife">
            <null></null>
        </property>
        <property name="info">
            <props>
                <prop key="Student id">20</prop>
                <prop key="Gender">male</prop>
                <prop key="Nationality">China</prop>
            </props>
        </property>
    </bean>
</beans>
Copy the code

The test class

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        Student student = (Student) context.getBean("student");
        System.out.println(student.getName());
    }
Copy the code

Results:

Injection of expansion approach

There are mainly p namespace injection and C namespace injection

Entity class

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

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

    public String getName(a) {
        return name;
    }

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

    public int getAge(a) {
        return age;
    }

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

    @Override
    public String toString(a) {
        return "User{" +
                "name='" + name + '\' ' +
                ", age=" + age +
                '} '; }}Copy the code
<! -- p namespace injection, can directly inject the value of the property: property-->
    <bean id="user" class="com.mq.pojo.User" p:name="xiaoqian" p:age="20"/>
    
<! -- c namespace injection, via constructor: construct-args-->
    <bean id="user2" class="com.mq.pojo.User" c:age="18" p:name="xiaoxioa"/>
Copy the code

Note: The p and C namespaces cannot be used directly, requiring XML import constraints

 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:c="http://www.springframework.org/schema/c"
Copy the code

Test result: p named injection:

C Named injection:

Note: C namespace injection works by using constructor injection, so you must add a parameter constructor to the entity class

Spongebob squarepants, that’s enough for today’s study, and study again tomorrow!