1. What is IOC?
IOC-Inversion of Control. It’s not a technology, it’s a design idea.
Whereas the traditional way to create objects is directly through the new keyword, Spring creates objects through the IOC container, which means we give control of object creation to the IOC container. IOC can be summed up in one sentence:
IOC lets programmers focus not on how objects are created, but on what happens after they are created, leaving the creation, initialization, and destruction of objects to the Spring container.
2. Share a simple explanation of IoC and DI from Bromon’s blog
IoC (Inversion of Control) This is at the heart of Spring, throughout. IoC, for the Spring framework, means that Spring is responsible for controlling the life cycle of objects and the relationships between objects. What does that mean, to take a simple example, how do we find a girlfriend? The common situation is that we go around to see where there are beautiful and nice MMS, and then ask about their interests, QQ number, telephone number, IP number, IQ number… Find a way to get to know them, give them what they want, and heh heh… The process is complex and profound, and we have to design and face each step ourselves. In traditional program development, if you want to use another object in an object, you have to get it (new one yourself, or look it up from JNDI) and then destroy the object (Connection, etc.). The object is always coupled with other interfaces or classes.
So what does the IoC do? It was a bit like finding a girlfriend through a matchmaking agency, which introduced a third party between me and my girlfriend: the matchmaking agency. Matchmaking management a lot of data of men and women, I can put forward to dating a list, telling it what I want to find a girlfriend, look like michelle reis, for example, figure like Lin Xilei, singing like jay Chou, speed technology like zinedine zidane, like carlos, then dating would, according to the requirements of our provide a mm, We just need to fall in love with her and get married. Plain and simple, if the matchmaker gives us someone who doesn’t meet our criteria, we throw an exception. The whole process is no longer controlled by me, but controlled by the matchmaking agency, which is like a vessel. That’s what Spring is all about. All the classes register in the Spring container, tell Spring what you are and what you need, and Spring will give you what you want when the system is running properly, and hand you over to other things that need you. The creation and destruction of all classes is controlled by Spring, which means that it is not the reference object that controls the life cycle of an object, but Spring. For a specific object, it used to control other objects, but now all objects are controlled by Spring, so this is called inversion of control.
The Spring container creates objects in three ways
Step 1: Create the project and import the corresponding JAR package as shown below: (See source code download above for details)
Step 2: Create the test object HelloIoc
1
2
3
4
5
6
7
8
|
package com.ys.ioc;
// This is the test object, which we create through IOC
public class HelloIoc {
public void sayHello(){
System.out.println( "Hello IOC" );
}
}
|
The traditional way to create an object: the new keyword
1
2
3
4
5
6
|
// The traditional method of creating an object ----new
@Test
public void testTradition(){
HelloIoc hello = new HelloIoc();
hello.sayHello();
}
|
How do we create this from the Spring container?
The first method: use the default constructor
Create a new applicationContext. XML file in the SRC directory, which is the Spring configuration file, and add the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<? 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 first way to create an object is to use a no-parameter constructor
Id: unique identifier
class : The full class name of the class
-->
<bean id= "helloIoc" class = "com.ys.ioc.HelloIoc" ></bean>
<! -- Alias attribute name: corresponds to the bean id attribute -->
<alias name= "helloIoc" alias= "helloIoc2" />
</beans>
|
Test code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/ * *
The Spring container uses constructors to create objects
* /
@Test
public void testCreateObjectByConstrutor(){
// Start the spring container
ApplicationContext context =
new ClassPathXmlApplicationContext( "applicationContext.xml" );
// Get data from the spring container
HelloIoc IOC = (HelloIoc) context.getBean( "helloIoc" );
// call a method from an object
IOC.sayHello();
// Create an object using the alias property of the configuration file
HelloIoc IOC2 = (HelloIoc) context.getBean( "helloIoc2" );
IOC2.sayHello();
}
|
We could manually add the constructor with no arguments to the test class helloioc.java, and then execute the above test code to see that the constructor is called before the sayHello() method is executed.
The second method: use the static factory method
Start by creating the helloStaticFactory.java static factory class
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.ys.ioc;
public class HelloStaticFactory {
public HelloStaticFactory(){
System.out.println( "HelloStaticFactory constructor" );
}
Static factory method
public static HelloIoc getInstances(){
return new HelloIoc();
}
}
|
Apply the following configuration in applicationContext.xml:
1
2
3
4
5
6
|
<! --
The second way to create an object is to use the static factory method
Factory-method: Static method of the static factory class to get an object
class : The full class name of the static factory class
-->
<bean id= "helloStaticFactory" factory-method= "getInstances" class = "com.ys.ioc.HelloStaticFactory" ></bean>
|
Writing test classes:
1
2
3
4
5
6
7
8
9
10
11
|
/ * *
* The Spring container uses static factory methods to create objects
* /
@Test
public void createObjectStaticFactory(){
ApplicationContext context =
new ClassPathXmlApplicationContext( "applicationContext.xml" );
HelloIoc staticFactory =
(HelloIoc) context.getBean( "helloStaticFactory" );
staticFactory.sayHello();
}
|
Note: The Spring container is only responsible for calling the static factory method, and the internal implementation of this static factory method is done by the programmer
Third method: use the instance factory method
Start by creating the instance factory class HelloInstanceFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.ys.ioc;
public class HelloInstanceFactory {
public HelloInstanceFactory(){
System.out.println( "Instance Factory method constructor" );
}
// Create an object using the instance factory method
public HelloIoc getInstance(){
HelloIoc instanceIoc = new HelloIoc();
return instanceIoc;
}
}
|
Apply the following configuration in applicationContext.xml:
1
2
3
4
5
6
7
8
|
<! --
The third way to create objects is by using the instance factory method
Factory-bean: Specifies the beanID of the current Spring containing the factory method
Factory-method: indicates the name of a factory method
-->
<bean id= "instanceFactory" class = "com.ys.ioc.HelloInstanceFactory" ></bean>
<bean id= "instance" factory-bean= "instanceFactory" factory-method= "getInstance" ></bean>
|
Finally, write the test class:
1
2
3
4
5
6
7
8
9
10
11
|
/ * *
* The Spring container creates objects using the instance factory method
* /
@Test
public void createObjectInstanceFactory(){
ApplicationContext context =
new ClassPathXmlApplicationContext( "applicationContext.xml" );
HelloIoc staticFactory =
(HelloIoc) context.getBean( "instance" );
staticFactory.sayHello();
}
|
4. When the Spring container creates objects
First: By default, objects are created by starting the Spring container (objects are created when beans are encountered)
Testing:
Step 1: We add the default constructor to helloioc.java:
Step 2: Add beans to the applicationContext.xml file (there are already three beans in the applicationContext.xml file since we created the object in three ways above)
Step 3: Start the Spring container and see how many times the no-argument constructor is printed
The console output is as follows:
Lazy init=”default/true/false”
If lazy-init is “default/false”, create object when spring container is started (default)
If lazy-init is “true”, the object will be created when context.getBean is used
We test lazy-init= “true”
We tested debugging through breakpoints:
Then proceed below:
In the first case, you can check the correctness of the Spring container configuration file when you start the spring container. If the Spring container does not start properly, tomcat will not start properly. However, the disadvantage is that some beans are put into memory too early, which is a drain on memory if there is data.
Conversely, in the second case, memory consumption is reduced, but errors are not easily detected
5, the scope of the spring bean, “singleton/prototype/request/session/global session”
The default scope value is singleton, that is, the generated object is singleton
Applicationcontext.xml:
1
|
<bean id= "helloIoc" scope= "singleton" class = "com.ys.ioc.HelloIoc" ></bean>
|
Validation:
1
2
3
4
5
6
7
8
|
Scope ="singleton" scope="singleton"
@Test
public void test_scope_single_CreateObject(){
ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml" );
HelloIoc hello1 = (HelloIoc) context.getBean( "helloIoc" );
HelloIoc hello2 = (HelloIoc) context.getBean( "helloIoc" );
System.out.println(hello1.equals(hello2)); //true
}
|
Second, the scope = “prototype”
Multi-case pattern, and the Spring container does not create objects when it starts, but when it gets the bean
Applicationcontext.xml:
1
|
<bean id= "helloIoc" scope= "prototype" class = "com.ys.ioc.HelloIoc" ></bean>
|
Validation:
1
2
3
4
5
6
7
8
|
Scope ="prototype" scope="prototype"
@Test
public void test_scope_prototype_CreateObject(){
ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml" );
HelloIoc hello1 = (HelloIoc) context.getBean( "helloIoc" );
HelloIoc hello2 = (HelloIoc) context.getBean( "helloIoc" );
System.out.println(hello1.equals(hello2)); //false
}
|
Summary: In singleton mode, when the Spring container is started, objects are created; In multi-case mode, objects are not created when the container is started, but when the bean is acquired
5. Spring container lifecycle
Create SpringLifeCycle. Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.ys.ioc;
/ * *
* Spring container lifecycle
* @author hadoop
*
* /
public class SpringLifeCycle {
public SpringLifeCycle(){
System.out.println( "SpringLifeCycle" );
}
// Define the initialization method
public void init(){
System.out.println( "init..." );
}
// Define the destruction method
public void destroy(){
System.out.println( "destroy..." );
}
public void sayHello(){
System.out.println( "say Hello..." );
}
}
|
applicationContext.xml
1
2
|
<! -- Life cycle -->
<bean id= "springLifeCycle" init-method= "init" destroy-method= "destroy" class = "com.ys.ioc.SpringLifeCycle" ></bean>
|
Testing:
1
2
3
4
5
6
7
8
9
10
11
12
|
// Initialization and destruction of the Spring container
@Test
public void testSpringLifeCycle(){
ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml" );
SpringLifeCycle hello = (SpringLifeCycle) context.getBean( "springLifeCycle" );
hello.sayHello();
// Destroy the Spring container
ClassPathXmlApplicationContext classContext = (ClassPathXmlApplicationContext) context;
classContext.close();
}
|
The console prints the following:
Analysis: The declaration cycle of the Spring container
1, Spring container create object 2, init method 3, call your own method 4, when spring container closed destroy method
Note: When scope is “prototype”, the close () method is not called destroy