spring的IoC(Inversion of Control)

In the official document , click on the Corecore package and open it, and you can find that the opening chapter is about IoCcontainers. So first understand IoC. As usual, starting from Baidu entries :

Inversion of control ( Inversion of Control, abbreviated as IoC), is a design principle in object-oriented programming that can be used to reduce the degree of coupling between computer codes . The most common method is called dependency injection ( Dependency Injection, for short DI), and another method is called "dependency lookup" ( Dependency Lookup). Through inversion of control, when an object is created, an external entity that regulates all objects in the system passes the references of the objects it depends on to it. It can also be said that the dependency is injected into the object.
The IoCpattern can be regarded as the sublimation of the factory pattern, and the IoCcontainer as a big factory, but the objects to be generated in this big factory are all XMLdefined in the file. Using Javathe "reflection" programming, the corresponding object is generated according to the class definition given in XML. From the point of view of implementation, for objects that were previously written dead in the factory mode, the IoCmode is changed to a configuration XML file, which isolates the factory and the objects to be generated, which greatly improves the flexibility and maintainability. IoCThe most basic Javatechnology in the middle is "reflective" programming. In layman's terms, reflection is to generate objects based on the given class name (string). This programming method allows the application to dynamically decide which object to generate at runtime.

In other words, it IoCis a programming idea , mainly used to reduce the coupling between codes. Specifically, when creating an object, you do not need to use the classic newto create the object, but use reflection, combined with xmlthe isolation of the factory object and the production object, which improves flexibility.

In previous webproject development, we usually write the following implementations:

  • Dao, DaoImpl
  • Service、ServiceImpl

That is, when loading data, if there are multiple implementations, we need to write multiple implementation classes that inherit specific interfaces, such as:
daolayer UserDaoand UserDaoImpltwo classes, respectively:

public interface UserDao {
    
    
    String getUserName();
}
public class UserDaoImpl implements UserDao {
    
    
    @Override
    public String getUserName() {
    
    
        return "User!";
    }
}

Then, you can write a servicelayer, which contains two classes, UserServiceand UserServiceImpltwo, respectively, the contents are:

public interface UserService {
    
    
    void getUserName();
}
public class UserServiceImpl implements UserService{
    
    
    UserDao userDao = new UserDaoImpl();

    @Override
    public void getUserName() {
    
    
        System.out.println(userDao.getUserName());
    }
}

Then we write a test class, such as:

class UserServiceImplTest {
    
    

    UserService userService = new UserServiceImpl();
    @Test
    void getUserName() {
    
    
        userService.getUserName();
    }
}

Project is structured as follows:
Insert picture description here
Test Results:
Insert picture description here
The above is a simple call, it seems there is no problem, but when our Daolevel, if there are multiple realization of the time, you need to modify the corresponding ServiceImplin the Daoimplementation, we can achieve the underlying data The source switch. Obviously, it cannot be dynamically adapted to the needs of development.
Solution: use setto dynamically set

public class UserServiceImpl implements UserService{
    
    
    UserDao userDao;

    // 动态注入
    public void setUserDao(UserDao dao){
    
    
        this.userDao = dao;
    }

    @Override
    public void getUserName() {
    
    
        System.out.println(userDao.getUserName());
    }
}
// 此时的测试类
class UserServiceImplTest {
    
    

    UserService userService = new UserServiceImpl();
    @Test
    void getUserName() {
    
    
        ((UserServiceImpl)userService).setUserDao(new UserDaoImpl());
        userService.getUserName();
    }
}

In this way, it is possible to dynamically set the changes of the underlying data source, and it is easier to adapt to customer service needs and dynamic modifications.
There is a thought here: the original initiative of the underlying data source is in the hands of the programmer, but with the current setinjection method, the initiative is in the hands of the person who needs to call, so that others can call what method they need. This idea is the inversion of control.


Video address: https://www.bilibili.com/video/BV1WE411d7Dv?p=3

Guess you like

Origin blog.csdn.net/qq_26460841/article/details/115024207