The article is hostedGitHub, you can go to GitHub to read, welcome to Star! Search wechat public code out of Offer to receive a variety of learning materials!

Deep understanding of Spring IOC (Inversion of Control)


I. Overview of IOC

Inverse Of Controll is IOC.

Simply put, IOC reverses the way dependencies are satisfied, from creating them themselves to pushing them by factories. It resolves the strong coupling between components that have dependencies, making the project shape more robust

What is IOC?

2.1 Understand IOC ideas

We have generally understood that IOC is inversion of control, but now we are not clear about its idea and function. So the question is, what is IOC?

Inversion of control, or IOC. As the name suggests, it is a combination of the words “control” and “inversion”. So let’s follow through and analyze these two words respectively!

2.2 control

The word control, we have a lot to think about. For example, the conditions for achieving control must be two objects, and control can be divided into who controls whom and what you do. Let’s list them one by one:

  1. In Java, we create objects in the new way. The developer controls the development tool and indirectly controls the dependent objects that the program needs to create. For the program, it directly controls the creation of objects. What about IOC? That would give the IOC container direct control over creating objects
  2. Since IOC controls object creation, how does it control object creation? Creating objects using IOC requires labels to bring in external objects, demonstrating that the IOC container controls the entry point for creating dependent objects

2.3 reverse

We think a lot about inversion. For example, there must be two objects for a reversal, and then there must be a positive inversion, and then there must be something reversed. So let’s list them one by one:

  1. In Java we create objects as indirect utilities, which can be seen as forward transformations. With the IOC container, all of a sudden, we don’t have to create our own new objects. Instead, we go straight back and create dependent objects for IOC and store them in the IOC container
  2. Use IOC container to create objects we just need to configure it to tell it what objects need to create, and identify the future use of the IOC container to obtain the created objects (configure the process of using IOC), at this time, you want to use the IOC container directly to obtain the object with this unique identifier. The retrieval process must be for IOC to find and return the object to us by this unique identifier
  3. Maybe some friends still don’t understand the inversion. Why is the IOC container’s help in creating objects called inversion? Because the container helps us find and inject dependent objects, objects passively accept dependent objects. What if you don’t reverse it? The developer needs to create the object and find, get, and use it, all of which is under the developer’s control

3. The role of IOC

With inversion of control, when an object is created, it is passed a reference to the object on which it depends by an external entity that regulates all objects in the system. In other words, dependencies are injected into objects.

For example, Class A uses the object B of Class B. In general, you need to explicitly new the object B in the code of A.

What about after using IOC? A’s code only needs to define A private B object. Instead of obtaining the object directly, it uses the relevant container controller to externally new the B object and inject it into A reference in class A. The method and state of the object are specified by the configuration file (XML)

Now that the configuration file specifies the creation of object relationships, it greatly reduces the strong coupling between components and facilitates maintenance, making the project more robust and flexible

Fourth, IOC resolves the strong coupling between the Dao layer and the Service layer

In the original Web development, the Dao layer and the Service layer were inseparable. The Dao layer is the data access layer and only deals with databases. The Servcie layer is the business processing layer and only deals with implementing the corresponding business. To string the Dao and Service layers together in Web development, we need to create a new private Dao layer implementation object (XxxDaoImpl) in the Service layer. With the idea of IOC, think about the implementation of the traditional Dao layer and Service layer is not flexible, once the Dao layer implementation class is modified, it is necessary to modify the source code in the project, is obviously a very terrible thing.

5. Use IOC to solve the strong coupling between Dao layer and Service layer

To solve the strong coupling between the Dao layer and the Service layer, you need these two components.

Dao layer

// Dao layer interface
package com.mylifes1110.dao;

import com.mylifes1110.bean.User;

public interface UserDao {
    int insertUser(User user);
}

// The Dao layer implements classes
package com.mylifes1110.dao.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;

public class UserDaoImpl implements UserDao {

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserDao------");
        return 0; }}Copy the code

Note: When we use IOC, we must inject the Dao layer implementation object into the IOC container. There must be an injection method to tell the IOC container to create and obtain objects. In the Service layer, we do not need the new implementation object. Instead, create a Setter method for the Service layer to inject UserDaoImpl dependencies into the UserServcieImpl. The method used is called Setter method dependency injection. I will list all the ways of dependency injection and analyze the idea of dependency injection and the relationship between dependency injection and IOC.

The Service layer

// Service layer interface
package com.mylifes1110.service;

import com.mylifes1110.bean.User;

public interface UserService {
    int insertUser(User user);
}

// Service layer implementation class
package com.mylifes1110.service.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserService------");
        return userDao.insertUser(null); }}Copy the code

spring-context.xml

<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd"> <! - id: a unique identifier class: need to be created fully qualified name of target object - > < bean id = "UserDao" class = "com. Mylifes1110. Dao. Impl. UserDaoImpl" / > <! - id: a unique identifier class: need to be created fully qualified name of target object - > < bean id = "UserService" class = "com. Mylifes1110. Service. Impl. UserServiceImpl" > <! <property name="userDao" ref=" userDao" /> </bean> </beans>Copy the code

The test class

/ * * *@MethodName insertUser1
* @Param []
* @DescriptionTest the use of IOC *@Author Ziph
* @Date2020/7/12 * /
@Test
public void insertUser1(a) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
    UserService userService = (UserService) context.getBean("UserService");
    userService.insertUser(null);
    // Print the result
    ------insertUser and UserService------
    ------insertUser and UserDao------
}
Copy the code