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