Spring — IOC, Di, auto assembly

Time:2021-11-20

What is IOC

The full name of IOC is inversion of control,The so-called control reversal is for the program itselfIn the past, we used to create objects by ourselves through new, but now we give this power to spring to help us create and manage objects, and the control over objects is reversed to spring

What is di

The full name of Di is dependency injection,The so-called dependency injection is for spring’s IOC containerIn the past, there were two channels for assigning values to the attributes of objects, one is through the construction method with parameters, and the other is through the set method. Now the IOC container injects the value of the attribute while creating the object.
What is dependency: for example, if there is a B object in the attribute of a object, it is called a dependency B

Di instance of spring

  • There are two ways of dependency injection, one is the object-based constructor, and the other is the set method based on the object attribute object. The basic implementation idea is as follows:

    • Based on constructor: Spring refers to the bean configuration, extracts the parameters of the bean object, and instantiates the bean object through the construction method
    • Attribute based set square
    • Method: Spring refers to the bean configuration. First, instantiate the bean object through the parameterless construction method, and then set the properties of the bean object through the set method
  • Inject basic data types (8 basic data classes + string)
/* User.java */
public class User {
     private String account;
     private String password;
     private Float balance;
     public User(String account, String password, Float balance) {
            this.account = account;
     this.password = password;
     this.balance = balance;
     }
        public User(){
            System.out.println ("user object created");
     }
        @Override
     public String toString() {
            return "User{" +
                    "account='" + account + ''' +
                    ", password='" + password + ''' +
                    ", balance=" + balance +
                    '}';
     }
        public String getAccount() {
            System. Out. Println ("set method called");
     return account;
     }
        public void setAccount(String account) {
            this.account = account;
     }
        public String getPassword() {
            return password;
     }
        public void setPassword(String password) {
            this.password = password;
     }
        public Float getBalance() {
            return balance;
     }
        public void setBalance(Float balance) {
            this.balance = balance;
     }
}
/*Main function*/
public class TestMain {
    public static void main(String[] args) {
         System.out.println(userDao.selectUserByAccount("2018"));
         AbstractApplicationContext factory = new ClassPathXmlApplicationContext("ApplicationContext.xml");
         User user = (User) factory.getBean("user");
         System.out.println(user);
     }
}
<!--  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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="user" class="com.cjh.domain.User">
         <property name="account" value="2019"></property>
         <property name="password" value="123"></property>
         <property name="balance" value="777"></property>
     </bean>
</beans>

If it is a basic data type / string, write the value to be passed directly through value, and the bottom layer will convert value into the corresponding data type according to the specific type of the attribute

  • Inject aggregate object

    • If another object is nested in an object, there are two ways to write it: one is to configure a bean in the bean, and the other is to introduce an external bean in the bean
    • The first way to write

      /* person.java */
      public class Person {
           private String name;
           //The above user object is introduced
           private User user;
           public Person(){}
              @Override
           public String toString() {
                  return "Person{" +
                          "name='" + name + ''' +
                          ", user=" + user +
                          '}';
           }
              public String getName() {
                  return name;
           }
              public void setName(String name) {
                  this.name = name;
           }
              public User getUser() {
                  return user;
           }
              public void setUser(User user) {
                  this.user = user;
           }
      }
      //Main function
      public class TestMain {
           public static void main(String[] args) {  
                   System.out.println(userDao.selectUserByAccount("2018"));
                   ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
                   Person person = (Person) context.getBean("person");
                   System.out.println(person);
           }
      }
      <!--  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
       https://www.springframework.org/schema/beans/spring-beans.xsd">
           <bean id="person" class="com.cjh.domain.Person">
               <property name="name" value="john"></property>
               <property name="user">
                   <bean id="user" class="com.cjh.domain.User">
                       <property name="account" value="2019"></property>
                       <property name="password" value="123"></property>
                       <property name="balance" value="777"></property>
                   </bean>
               </property> 
           </bean>
      </beans>
    • The second way to write

      • An external variable is introduced through the ref attribute in the property tag
<!--  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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="person" class="com.cjh.domain.Person">
         <property name="name" value="john"></property>
         <property name="user" ref="user"></property>
     </bean>
     <bean id="user" class="com.cjh.domain.User">
         <property name="account" value="2019"></property>
         <property name="password" value="123"></property>
         <property name="balance" value="777"></property>
     </bean>
</beans>
  • Injection set

    • Inject list, set, map, properties collection
//TestCollection.java
package com.cjh.domain;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class TestCollection {
     private List<String> list;
     private Set<String> set;
     private Map<Integer, String> map;
     private Properties properties;
     public TestCollection(){}
        @Override
     public String toString() {
            return "TestCollection{" +
                    "list=" + list +
                    ", set=" + set +
                    ", map=" + map +
                    ", properties=" + properties +
                    '}';
     }
        public List<String> getList() {
            return list;
     }
        public void setList(List<String> list) {
            this.list = list;
     }
        public Set<String> getSet() {
            return set;
     }
        public void setSet(Set<String> set) {
            this.set = set;
     }
        public Map<Integer, String> getMap() {
            return map;
     }
        public void setMap(Map<Integer, String> map) {
            this.map = map;
     }
        public Properties getProperties() {
            return properties;
     }
        public void setProperties(Properties properties) {
            this.properties = properties;
     }
    }
//Main function
public class TestMain {
    public static void main(String[] args) {
      System.out.println(userDao.selectUserByAccount("2018"));
     ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
     TestCollection collection = (TestCollection) context.getBean("testCollection");
     System.out.println(collection);
     }
}
<!--  Configuration information -- >
<?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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="testCollection" class="com.cjh.domain.TestCollection">
         <property name="list">
             <list value-type="java.lang.String">
                 <value>12</value>
                 <value>13</value>
                 <value>14</value>
                 <value>15</value>
             </list> 
         </property> 
         <property name="set">
             <set value-type="java.lang.String">
                 <value>abc</value>
                 <value>def</value>
                 <value>ghi</value>
                 <value>jkl</value>
                 <value>mno</value>
             </set> 
         </property> 
         <property name="map">
             <map key-type="java.lang.Integer" value-type="java.lang.String">
                 <entry key="1" value="a"/>
                 <entry key="2" value="b"/>
                 <entry key="3" value="c"/>
             </map> 
         </property> 
         <property name="properties">
             <props value-type="String">
                 <prop key="a">1</prop>
                 <prop key="b">2</prop>
                 <prop key="c">3</prop>
             </props>
         </property> 
     </bean>
</beans>
  • Inject null and empty strings
<bean id="person" class="com.cjh.domain.Person">
 <property name="name" value=""></property>
 <property name="user">
 <null></null> </property></bean>

In the above configuration, value defaults to an empty string without giving anything. If you need to inject null, you need to use the null tag. If you directly use value = “null”, spring will parse it into a null string

automatic assembly

  • Byname: when obtaining the current bean object, a bean object with the same ID / name attribute will be found under the configuration file according to the property name of the current object and assembled to the current bean object (through the set method of the attribute)

    • Note: I have tried manually here. When the attribute name is inconsistent with the name / ID name of the bean tag, but the attribute name of the set method (naming rule of the set method: Set + attribute name) is consistent with the name / ID, the assembly can also be successful
    • So I come to the conclusion that spring matches the name / ID in the bean tag according to the suffix attribute name of the set method (personal opinion)
  • Bytype: when obtaining the current bean object, find the bean object of the same type under the configuration file according to the type of the current object property and assemble it to the current bean object (through the set method of the property)

    • If there are multiple bean objects of the same type under beans, an error will be reported
    • If the property type of the current bean object is the parent of an interface, abstract class or ordinary class, there are three cases

      • When the parameters of the set method corresponding to the attribute are also of the above three types, if there is only one matching instantiatable type (subclass / parent class of ordinary class) under beans, the assembly is successful
      • If the parameters of the set method corresponding to the attribute are also of the above three types, but there are multiple matching instantiatable types under beans, an error is reported
      • When the parameter of the set method corresponding to the attribute is an instantiatable type and there is only one matching type under beans, the assembly is successful. If there are multiple, an error is reported
  • Constructor: assemble according to the construction method with parameters

    • According to whether the parameter name of the construction method is consistent with the ID / name name of the bean tag
    • According to whether the parameter type of the constructor is consistent with the class type of the bean tag

      • If the parameter type of the constructor is a parent class, there must be a unique matching bean object under beans (multiple non assemblies occur)
    • If the above two points meet one of them, it can be assembled
  • No: automatic assembly is not supported