In the official document , click on the Core
core package and open it, and you can find that the opening chapter is about IoC
containers. So first understand IoC
. As usual, starting from Baidu entries :
Inversion of control (
Inversion of Control
, abbreviated asIoC
), 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 shortDI
), 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.
TheIoC
pattern can be regarded as the sublimation of the factory pattern, and theIoC
container as a big factory, but the objects to be generated in this big factory are allXML
defined in the file. UsingJava
the "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, theIoC
mode is changed to a configuration XML file, which isolates the factory and the objects to be generated, which greatly improves the flexibility and maintainability.IoC
The most basicJava
technology 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 IoC
is a programming idea , mainly used to reduce the coupling between codes. Specifically, when creating an object, you do not need to use the classic new
to create the object, but use reflection, combined with xml
the isolation of the factory object and the production object, which improves flexibility.
In previous web
project 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:
dao
layer UserDao
and UserDaoImpl
two classes, respectively:
public interface UserDao {
String getUserName();
}
public class UserDaoImpl implements UserDao {
@Override
public String getUserName() {
return "User!";
}
}
Then, you can write a service
layer, which contains two classes, UserService
and UserServiceImpl
two, 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:
Test Results:
The above is a simple call, it seems there is no problem, but when our Dao
level, if there are multiple realization of the time, you need to modify the corresponding ServiceImpl
in the Dao
implementation, we can achieve the underlying data The source switch. Obviously, it cannot be dynamically adapted to the needs of development.
Solution: use set
to 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 set
injection 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