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
- 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
- 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)
- 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!