Spring IoC (Inversion of Control)

IoC is the abbreviation of Inversion of Control, translated as "Inversion of Control". It is not a technology, but a design idea and an important object-oriented programming rule.
Spring manages the instantiation and initialization of all Java objects through the IoC container, and controls the dependencies between objects. We call the Java objects managed by the IoC container Spring Beans, and there is no difference between them and the Java objects created using the keyword new. The IoC container is one of the most important core components in the Spring framework. It runs through the entire process of Spring from its birth to its growth.

Inversion of Control (IoC)

In traditional Java applications, if a class wants to call a property or method in another class, it usually creates the latter object through new Object() in its code, and then implements the property or method. transfer. For ease of understanding and description, we can call the former the "caller" and the latter the "callee". In other words, the caller has control over the creation of the callee object.

But in Spring applications, the control of Java object creation is in the hands of the IoC container. The general steps are as follows.

  1. Developers define Java objects through XML configuration files, annotations, Java configuration classes, etc., such as using <bean> tags in XML configuration files, using @Component annotations on Java classes, etc.
  2. When Spring starts, the IOC container will automatically create and manage these objects based on object definitions. These objects created and managed by the IOC container are called Spring Beans.
  3. When we want to use a Bean, we can get it directly from the IOC container (for example, through the getBean() method of ApplicationContext) without manually creating it through code (for example, new Obejct()).


The biggest change brought about by IoC is not at the code level, but at the ideological level, the change of "master-slave transposition". Originally, the caller was the active party, and would take the initiative and create whatever resources it wanted to use. However, in Spring applications, the IoC container holds the initiative, and the caller became the passive party, passively waiting for the IoC container. Create the objects (Beans) it requires.

This process has an inversion of control at the responsibility level, reversing the creation of objects originally implemented by the caller through code to the IoC container to help implement it, so we call this process Spring's "inversion of control".

Dependency Injection (DI)

After understanding IoC, we also need to understand another very important concept: dependency injection.

Dependency Injection (DI) was proposed by Martin Fowler in 2004 when explaining "Inversion of Control". Martin Fowler believes that the term "inversion of control" is very obscure and does not allow people to directly understand "where the inversion is", so he suggested using "dependency injection" instead of "inversion of control".

In object-oriented, there is a relationship called "dependency" between objects. Simply put, a dependency relationship means that one object needs to use another object, that is, there is an attribute in the object, and the attribute is an object of another class.

For example, there is a Java class named B with the following code. 

public class B {
    String bid;
    A a;
}

As can be seen from the code, there is an object attribute a of type A in B. At this time, we can say that the object of B depends on the object a. Dependency injection is based on this "dependency relationship".

The core idea of ​​inversion of control is that Spring is responsible for the creation of objects. During the object creation process, Spring will automatically inject the objects it depends on into the current object based on the dependency relationships. This is the so-called "dependency injection".

How IoC works

In the Java software development process, there are more or less coupling relationships between various objects in the system, between various modules, and between software systems and hardware systems.

If the coupling of a system is too high, it will cause problems that are difficult to maintain, but code with no coupling at all can hardly complete any work. This is because almost all functions require cooperation and interdependence between codes to complete. Therefore, when we design programs, the idea we adhere to is generally to reduce the degree of coupling to the maximum extent without affecting the function of the system.

The bottom layer of IoC uses factory mode, Java's reflection mechanism, XML parsing and other technologies to reduce the coupling of the code to the minimum. The main steps are as follows.

  1. In the configuration file (such as Bean.xml), configure each object and the dependencies between them;
  2. We can think of the IOC container as a factory, and the product of this factory is Spring Bean;
  3. When the container starts, it will load and parse these configuration files to obtain basic information about the objects and the dependencies between them;
  4. IOC uses Java's reflection mechanism to generate a corresponding object (i.e. Spring Bean) based on the class name, and injects this object into objects that depend on it based on dependencies.

Since the basic information of objects and the dependencies between objects are defined in the configuration file and are not tightly coupled in the code, even if the object changes, we only need to modify it in the configuration file without Modify the Java code, this is the principle of Spring IOC decoupling.

Two implementations of IoC containers

The IoC idea is implemented based on the IoC container. The bottom layer of the IoC container is actually a Bean factory. The Spring framework provides us with two different types of IoC containers, namely BeanFactory and ApplicationContext.

BeanFactory

BeanFactory is the basic implementation of the IoC container and the simplest IoC container provided by Spring. It provides the most basic functions of the IoC container and is defined by the org.springframework.beans.factory.BeanFactory interface.

BeanFactory uses a lazy-load mechanism. The container does not create a Java object immediately when loading the configuration file. It will only be created when the object is obtained (used) in the program.

Example 1

Use of BeanFactory.

In the HelloSpring project, modify the MainApp code to use BeanFactory to obtain the HelloWorld object. The specific code is as follows. 

public static void main(String[] args) {
    BeanFactory context = new ClassPathXmlApplicationContext("Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 2Run MainApp.java, the console output is as follows.

message : Hello World!

BeanFactory is Spring's internal interface and is usually not available to developers.  

ApplicationContext

ApplicationContext is a sub-interface of the BeanFactory interface and an extension of BeanFactory. ApplicationContext adds many enterprise-level functions based on BeanFactory, such as AOP (aspect-oriented programming), internationalization, transaction support, etc.

The ApplicationContext interface has two commonly used implementation classes, as detailed in the following table.

Implementation class describe Sample code
ClassPathXmlApplicationContext Load the XML configuration file specified under the class path ClassPath and complete the instantiation of ApplicationContext ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);
FileSystemXmlApplicationContext Load the XML configuration file specified in the specified file system path and complete the instantiation of ApplicationContext ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

The parameter configLocation is used to specify the name and location of the Spring configuration file, such as Beans.xml.

Demonstrate the use of ApplicationContext 

Modify the code of the main() method in the MainApp class of the HelloSpring project. The specific code is as follows. 

public static void main(String[] args) {
    //使用 FileSystemXmlApplicationContext 加载指定路径下的配置文件 Bean.xml
    BeanFactory context = new FileSystemXmlApplicationContext("D:\\springworkspace\\
HelloSpring\\src\\Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 Run MainApp.java, the console output is as follows:

message : Hello World!

Guess you like

Origin blog.csdn.net/qq_43079001/article/details/132099030