Spring IOC: control inversion

Posted by bharrison89 on Thu, 10 Feb 2022 22:10:58 +0100

Steps for using the Spring framework

  1. Join dependency
  2. Create class: interface, implementation class and class without interface
  3. Create a Spring configuration file and declare it with < bean >
  4. Using the object in the container, use the method getBean() of ApplicationContext

IOC: control reversal

The implementation of ioc technology uses di (dependency injection): developers only need to provide the name of the object in the project, and the creation, search and assignment of the object are implemented by the container itself.

spring uses di technology, and the bottom layer uses reflection mechanism.

Creation of Spring objects

Implementation steps:

  1. Create maven project
  2. Add maven dependency: spring dependency, Junit dependency
  3. Create a class (interface and its implementation class), which is the same as ordinary class without using framework
  4. The configuration files needed to create spring and declare the information of classes. These classes are used for the creation and management of spring
  5. Test objects created by spring

spring creates an object of a custom class

Interface:

package com.springcode.service;

public interface SomeService {
    void doSome();
}

SomeServiceImpl class:

package com.springcode.service.Impl;

import com.springcode.service.SomeService;

public class SomeServiceImpl implements SomeService {

    public SomeServiceImpl() {
        System.out.println("SomeService Nonparametric construction method of");
    }

    @Override
    public void doSome() {
        System.out.println("Yes SomeServiceImpl of dosome method");
    }
}

beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        spring create object
        statement bean,Just tell spring To create an object of a class
        id:Custom name of the object, unique value, spring Find the object by this name
        class: The fully qualified name of the class (not an interface because spring Is a reflection mechanism to create an object, you must use a class)

    -->
 <!--
      spring Just do something similar Someservice someService = new SomeServiceImpl();
      spring Is to put the created object into map In, spring The frame has a map Storage object.
      springMap.put(id Value of, object);
      For example: springMap.put("someService", new SomeServiceImpl());

      One bean Label declares an object.
  -->
    <bean id="someService" class="com.springcode.service.Impl.SomeServiceImpl" />
    <bean id="someService1" class="com.springcode.service.Impl.SomeServiceImpl" />

</beans>

<!--
    spring Configuration file for
    1,beans It's a root tag, spring hold java Objects are called bean. 
    2,spring-beans.xsd Is a constraint file, and mybatis appoint dtd It's the same.
-->

Test class:

package com.springcode;

import com.springcode.service.Impl.SomeServiceImpl;
import com.springcode.service.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

        @Test
        public void test01() {
                SomeService service = new SomeServiceImpl();
                service.doSome();
        }

        /**
         * spring Default object creation time: when creating the Spring container, all objects in the configuration file will be created
         */

        @Test
        public void test02() {
                // Objects created using the spring container
                // 1. Specifies the name of the spring configuration file
                String config = "beans.xml";
                // 2. Create an object representing the spring container, ApplicationContext
                // ApplicationContext represents the Spring container and obtains objects through the container
                // ClassPathXmlApplicationContext: indicates the configuration file of spring loaded from the classpath
                ApplicationContext ac = new ClassPathXmlApplicationContext(config);

                // Get an object from the container and call the method of the object
                // getBean("id value of bean in configuration file")
                SomeService service = (SomeService) ac.getBean("someService");
                // Use the objects already created by spring
                service.doSome();

        }

        /**
         * Get the information of Java objects in spring container
         */
        @Test
        public void test03() {
                String config = "beans.xml";
                ApplicationContext ac = new ClassPathXmlApplicationContext(config);

                // Use the method provided by spring to get the number of objects defined in the container
                int nums = ac.getBeanDefinitionCount();
                System.out.println("Number of objects defined in the container:" + nums);

                // The name of each defined object in the container
                String[] names = ac.getBeanDefinitionNames();
                for(String name : names) {
                        System.out.println(name);
                }
        }

}

spring creates objects of non custom classes

beans.xml:

<!-- Create a date class
        Create an existing object of a class
    -->
    <bean id="mydate" class="java.util.Date" />

Test class:

		/**
         * Create a non custom class object
         */
        @Test
        public void test04() {
                String config = "beans.xml";
                ApplicationContext ac = new ClassPathXmlApplicationContext(config);
                // Use getBean();
                Date my = (Date) ac.getBean("mydate");
                System.out.println("Date:" + my);
        }
spring Create object: by default, the parameterless construction method is called

Assign values to attributes

Assign values to the properties of java objects through spring

  • DI: dependency injection, which means creating objects and assigning values to attributes.

  • There are two implementation syntax of DI:

    • In spring's configuration file, it is completed using tags and attributes, which is called XML based di implementation
    • Use the annotation in spring to complete the attribute assignment, and then do the id implementation based on the annotation
  • Syntax classification of di:

    • Set injection (set injection): spring calls the set method of the class, in which attribute assignment can be realized.
    • Construction injection: spring calls the parameterized construction method of the class, creates the object, and completes the assignment in the construction method.

Student class:

package com.springstudy.ba01;

public class Student {

    private String name;
    private int age;

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

di: assign values to attributes

Simple type: spring specifies that the basic data type and String of java are simple types.

Injection: it means assignment.

Injection classification

1. set injection

spring calls the set method of the class to complete the attribute assignment in the set method

1) Simple type set injection

<bean id="" class="">
    <property name="Attribute name" value="The value of this property" /> One property Only one property can be assigned a value
</bean>
ba01/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--statement student object-->
    <bean id="myStudent" class="com.springstudy.ba01.Student">
        <property name="name" value="Sean" />
        <property name="age" value="29" />
    </bean>

</beans>

junit

  • junit: unit test, a tool class library for test methods.

    • Unit: Specifies the method. There are many methods in a class. A method is called unit.
  • Using unit tests:

    1. junit dependency needs to be added

      	<!--  unit testing   -->
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
          </dependency>
      
    2. Create a test function class: test class

      Create classes in src/test/java directory

    3. Create test method

      • public method
      • No return value void
      • The method name is customized. The recommended name is test + the name of the method to be tested
      • Method has no parameters
      • Add @ test to the method, so that the method can be executed separately without using the main method

You can execute a method alone or all the methods in a class.

2) set injection of reference type

		<bean id="xxx" class="yyy">
            <property name="Attribute name" ref="bean of id(The name of the object zzz)" />
        </bean>

        <bean id="zzz" class="kkk">
            <property name="Attribute name" value="The value of this property" />
        </bean>

General category:

School class:

package com.springstudy.ba02;

public class School {

    private String name;
    private String Address;


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

    public void setAddress(String address) {
        Address = address;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", Address='" + Address + '\'' +
                '}';
    }
}

Student class:

package com.springstudy.ba02;

public class Student {

    private String name;
    private int age;

    // Declare a reference type
    private School school;

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

    public void setSchool(School school) {
        System.out.println("setSchool:" + school);
        this.school = school;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

Use property:

<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myStudent" class="com.springstudy.ba02.Student">
        <property name="name" value="Sean" />
        <property name="age" value="28" />
        <!--reference type-->
        <property name="school" ref="mySchool" />
    </bean>

    <bean id="mySchool" class="com.springstudy.ba02.School">
        <property name="name" value="Xiamen midsummer moon" />
        <property name="address" value="Xiamen" />
    </bean>
</beans>

2. Structural injection

Structural injection: spring Call the parameterized construction method of the class, and assign a value to the attribute in the construction method while creating the object.
  • Use label

    • One represents a parameter in the construction method. If there are three parameters in the construction method, three labels are required.
  • Label properties:

    • Name: indicates the formal parameter name of the constructor
    • index: indicates the position of the parameter of the construction method. The position of the parameter from left to right is: 0, 1, 2
    • Value: the formal parameter type of the constructor is a simple type. Use value
    • ref: the formal parameter type of the constructor is a reference type. Use ref
<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--use name Attribute implementation makes construction injection more readable -->
    <bean id="myStudent" class="com.springstudy.ba03.Student">
        <constructor-arg name="myName" value="Yibo" />
        <constructor-arg name="myAge" value="24" />
        <constructor-arg name="mySchool" ref="myCollege" />
    </bean>

    <!--use index attribute-->
    <bean id="myStudent01" class="com.springstudy.ba03.Student">
        <constructor-arg index="0" value="Li Si" />
        <constructor-arg index="1" value="22" />
        <constructor-arg index="2" ref="myCollege" />
    </bean>

    <!--Positions can be exchanged-->
    <bean id="myStudent02" class="com.springstudy.ba03.Student">
        <constructor-arg index="1" value="22" />
        <constructor-arg index="0" value="Li Si" />
        <constructor-arg index="2" ref="myCollege" />
    </bean>

    <!--index It can be omitted, but the order cannot be changed-->
    <bean id="myStudent03" class="com.springstudy.ba03.Student">
        <constructor-arg value="fabulous" />
        <constructor-arg value="22" />
        <constructor-arg ref="myCollege" />
    </bean>

    <!--statement School object-->
    <bean id="myCollege" class="com.springstudy.ba03.School">
        <property name="name" value="Xiamen midsummer" />
        <property name="address" value="Xiamen" />
    </bean>
</beans>

Construct injection to create file objects

	<!--establish File,Using structural injection-->
    <bean id="myfile" class="java.io.File">
        <constructor-arg name="parent" value="D:\TyporaNote\Spring" />
        <constructor-arg name="child" value="Spring5.md" />
    </bean>

myTest class:

File myFile = (File) ac.getBean("myfile");
System.out.println("myFile = " + myFile.getName());

Automatic injection of reference type attributes

Automatic injection of reference types: the spring framework can assign values to reference types according to certain rules.

  • Commonly used rules are byName and byType

(1) byName mode automatic injection

  • byName (injection by name): the attribute name of the reference type in the java class is the same as the id name in the spring container (configuration file), and the data type is the same. For bean s in such a container, spring can assign values to the reference type.

    • <bean id="xxx" class="yyy" autowire="byName">
          Simple type attribute assignment
      </bean>
      
<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        Automatic injection of reference types: spring The framework can assign values to reference types according to certain rules
    -->
    <bean id="student" class="com.springstudy.ba04.Student" autowire="byName">
        <property name="name" value="Sean" />
        <property name="age" value="29" />
        <!--reference type-->
        <!--<property name="school" ref="school" />-->
    </bean>
    
    <!--statement School object-->
    <bean id="school" class="com.springstudy.ba04.School">
        <property name="name" value="Chongqing Industrial and Commercial University" />
        <property name="address" value="Chongqing" />
    </bean>

</beans>

(2) byType mode automatic injection

  • byType (injection by type): the data type of the reference type in the java class and the class attribute in the spring container (configuration file) are homologous. Such bean s can be assigned to the reference type.

    <bean id="xxx" class="yyy" autowire="byType">
        Simple type attribute assignment
    </bean>
    
  • Homology means one kind

  • The data type of the reference type in the java class is the same as the class value of the bean.

<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        Automatic injection of reference types: spring The framework can assign values to reference types according to certain rules
    -->
    <bean id="student" class="com.springstudy.ba04.Student" autowire="byType">
        <property name="name" value="Yibo" />
        <property name="age" value="24" />
        <!--reference type-->
        <!--<property name="school" ref="school" />-->
    </bean>
    
    <!--statement School object-->
    <bean id="college" class="com.springstudy.ba04.School">
        <property name="name" value="Peking University" />
        <property name="address" value="Beijing" />
    </bean>

</beans>
  • The data type of reference type in java class and the class value of bean are parent-child relationship.

    package com.springstudy.ba04;
    
    public class School {
    
        private String name;
        private String Address;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAddress(String address) {
            Address = address;
        }
    
        public String getName() {
            return name;
        }
    
        public String getAddress() {
            return Address;
        }
    
        @Override
        public String toString() {
            return "School{" +
                    "name='" + name + '\'' +
                    ", Address='" + Address + '\'' +
                    '}';
        }
    }
    
    
    package com.springstudy.ba04;
    
    //Subclass
    public class PrimarySchool extends School{
    }
    
    
    <bean id="student" class="com.springstudy.ba04.Student" autowire="byType">
            <property name="name" value="Yibo" />
            <property name="age" value="24" />
            <!--reference type-->
            <!--<property name="school" ref="school" />-->
        </bean>
    
        <!--Declare a school Subclass of-->
        <bean id="primarySchool" class="com.springstudy.ba04.PrimarySchool">
            <property name="name" value="Chongqing Industrial and Commercial University" />
            <property name="address" value="Chongqing" />
        </bean>
    
  • The data type of reference type in java class and the value of class in bean are the interface and implementation relationship.

**In byType, beans are declared in the xml configuration file. There can only be one bean that meets the conditions. If there is more than one bean, an error will be reported**

Why use multiple profiles?

  • Multiple configuration advantages

    • The size of each file is much smaller and more efficient than that of one file
    • Avoid conflicts caused by multi player competition
    • If there are multiple modules in the project (related functions together), one module and one configuration file
  • Allocation method of multiple files:

    • By function module, one module and one configuration file
    • According to the function of the class, the configuration related to the database occupies a configuration file, the transaction function occupies a configuration file, and the service function occupies a configuration file
<?xml version="1.0" encoding="UTF-8"?>
<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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        The profile contains the relationship
        spring-total Indicates the main configuration file: contains other configuration files. Generally, the main configuration file does not define objects
        Syntax:<import resource="Path to other configuration files" />
        keyword:"classpath:"Path representation class( class (directory of the file)( target Directory classes)
        stay spring To specify the location of other files in the configuration file of, you need to use classpath,tell spring Where to load and read files

    -->
    <!--  Loading is a list of files  -->
	<!--    <import resource="classpath:ba05/spring-school.xml" />-->
	<!--    <import resource="classpath:ba05/spring-student.xml" />-->

    <!--
        Wildcards can be used(*: (represents any character)
        Note: the main profile name cannot be included in the range of wildcards, and these profiles need to be in the same directory
    -->
    <import resource="classpath:ba05/spring-*.xml" />

</beans>

Topics: Java Spring