Spring's core idea of IOC in-depth introduction

Spring's core idea of ​​IOC in-depth introduction

1. Dependence inversion principle

To understand inversion of control (Inversion of Control), I feel the need to understand the important idea of software design: Dependency Inversion Principle (Dependency Inversion Principle).

What is the principle of dependency inversion? Suppose we design a car: first design the wheels, then design the chassis according to the wheel size, then design the body according to the chassis, and finally design the entire car according to the body. Here is a "dependency" relationship: the car depends on the body, the body depends on the chassis, and the chassis depends on the wheels. This design seems to be no problem, but the maintainability is very low. Suppose that after the design is completed, the boss suddenly said that according to the changes in market demand, we should change the design of the wheels of the car by one size. This time we are painful: because we design the chassis according to the size of the wheels, if the size of the wheels is changed, the design of the chassis must be modified; also because we are designing the body based on the chassis, then the body must also be modified, and the same is true. The car design has to be changed too-almost the entire design has to be changed! Let's change our thinking now. We first design the general appearance of the car, then design the body according to the appearance of the car, design the chassis according to the body, and finally design the wheels according to the chassis. At this time, the dependency is reversed: the wheels depend on the chassis, the chassis depends on the body, and the body depends on the car. At this time, if the boss wants to change the design of the wheels, we only need to change the design of the wheels, not the design of the chassis, body, or car. This is the principle of reliance on the inversion—turning the original high-rise building dependent on the low-level building "upside down" and turning the low-level building dependent on the high-rise building. The high-rise building decides what is needed, and the bottom layer realizes such a requirement, but the high-rise building does not care how the bottom layer is realized. In this way, the previous situation of "pulling the whole body" will not occur.

2. Inversion of Control

Inversion of Control (Inversion of Control) is a code design idea that relies on the inversion principle. The specific method used is the so-called Dependency Injection (Dependency Injection). In fact, these concepts will feel in the mist at the first contact. To put it bluntly, the relationship between these concepts is roughly as follows: In order to understand these concepts, we still use the car example above. It's just a code this time. We first define four classes, car, body, chassis, and tires. Then initialize the car, and finally run the car. The code structure is as follows: In
this way, it is equivalent to the first example above. The superstructure depends on the lower structure-the constructor of each class directly calls the constructor of the underlying code. Suppose we need to change the tire (Tire) class to make its size dynamic instead of always being 30. We need to change it like this: Insert picture description hereSince we have modified the definition of the tire, in order to make the entire program run normally, we need to make the following changes:
From this we can see that just to modify the tire's constructor, this design needs to modify the entire upper layer. Constructors of all classes! In software engineering, such a design is almost unmaintainable-in actual engineering projects, some classes may be the bottom layer of thousands of classes. If we modify this class every time, we have to modify everything to depend on it. The maintenance cost of the software is too high.

So we need to perform inversion of control (IoC), and the upper layer controls the lower layer, instead of the lower layer controlling the upper layer. We use Dependency Injection to achieve inversion of control. The so-called dependency injection is to pass the bottom class as a parameter to the upper class to realize the "control" of the upper class to the lower class. Here we use the dependency injection method passed by the construction method to rewrite the definition of the car class: here we make the tire size dynamic. Also in order to make the entire system run smoothly, we need to make the following changes: see? Here I only need to modify the tire class, without modifying any other upper class. This is obviously easier to maintain code. Not only that, in actual projects, this design pattern is also conducive to the collaboration and unit testing of different groups: For example, the four types of development are four different groups, so as long as the interface is defined, the four are different. The group can be developed at the same time without being restricted by each other; and for unit testing, if we want to write a unit test of the Car class, we only need to mock the Framework class and pass it to Car instead of adding Framework, Bottom, and Tire all new Construct Car again and again. Here we are using the dependency injection method of the constructor passed in. In fact, there are two other methods: Setter transfer and interface transfer. I won’t go into more here. The core ideas are the same, all for the purpose of realizing inversion of control.
Seeing here you should be able to understand what inversion of control and dependency injection are. So what is an inversion of control container (IoC Container)? In fact, in the above example, the place where the code that initializes the car class occurs is the inversion of control container.
Obviously, you should also observe that, because dependency injection is used, a lot of new will inevitably be written during the initialization process. The IoC container here solves this problem. This container can automatically initialize your code, you only need to maintain a Configuration (can be xml can be a piece of code), instead of writing that large piece of initialization code by yourself every time you initialize a car. This is the first benefit of introducing IoC Container. The second benefit of IoC Container is that we don't need to understand the details when creating an instance. In the above example, when we manually create a car instance by ourselves, we start new from the bottom to the top: in this process, we need to understand how the entire Car/Framework/Bottom/Tire class constructor is defined in order to be new step by step. /injection. When IoC Container does this work, it is the reverse. It starts from the top layer to find dependencies, and after reaching the bottom layer, it goes one step by step. New (a bit like depth-first traversal):
Here IoC Container can be hidden directly The specific details of the creation of the instance, in our view, it is like a factory:
we are like the customers of the factory. We only need to request a Car instance from the factory, and then it creates a Car instance for us according to Config. We don't care about how this Car instance is created step by step. In actual projects, some Service Class may be written ten years ago, and there are hundreds of classes as its bottom layer. Suppose we need to instantiate this Service in a newly written API, we can never go back and figure out the constructors of these hundreds of classes, right? This feature of IoC Container perfectly solves this type of problem-because this architecture requires you to write the corresponding Config file when writing the class, so when you want to initialize the Service class long ago, the predecessors have already written it Once the Config file is complete, you can directly inject this Service where you need it. This greatly increases the maintainability of the project and reduces the difficulty of development.

Three. Summary

IOC thought:The core of ioc's thinking is that resources are not managed by the two parties who use the resource, but by a third party who does not use the resource, which can bring many benefits. First, centralized management of resources to achieve configurable and easy management of resources. Second, it reduces the degree of dependence on both sides of the resource, which is what we call the degree of coupling. In other words, Party A does not need to directly rely on Party B to achieve a certain purpose. It only needs to tell a third-party organization for the purpose achieved. For example, Party A needs a pair of socks, and Party B sells a pair of socks, and it wants to sell socks. Going out, you do not need to find a seller directly to complete the sale of socks. It also only needs to find a third party and tell them that I want to sell a pair of socks. This is all right. Both parties A and B do not need to go to the seller directly for transaction activities, which is equivalent to the internal open interface of the program, and the seller is passed in as a parameter by a third party. A and B do not depend on each other, and only in the transaction activities, A and B contact. vice versa. What is the advantage of this? A and B can exist independently when the other party does not really exist, and it is guaranteed that there is no contact when not trading, and they can easily be contacted when they want to trade. The transaction activities of A and B do not require the two parties to meet, which avoids the problem of transaction failure caused by mutual distrust between the two parties. Because the transaction is handled by a third party, and both A and B believe that the third party is reliable. Then the transaction can be generated and carried out very reliably and flexibly. This is the core idea of ​​ioc. Such examples abound in life. Alipay is a huge ioc container in the entire Taobao system. A third party other than both parties to the transaction can rely on a resource management center that can flexibly change the transaction party to provide reliability. In addition, personnel agencies are also third parties other than employment agencies and individuals.

Dependency injection: It can be understood that Party A opens the interface, and when it needs it, it can tell Party B to pass in (inject)
Inversion of control: It can be understood that both parties do not depend on each other, the transaction activities are not dependent on either party A or B, and the entire activity is managed by a third party.


Reprinted source:

> 作者:Mingqi 链接:https://www.zhihu.com/question/23277575/answer/169698662
> 作者:Eric   链接:https://www.zhihu.com/question/23277575/answer/24259844
> 来源:知乎

Guess you like

Origin blog.csdn.net/weixin_45496190/article/details/106441561