Spring6 – (01) case introduces the concept of Spring

image-20230206074352715

Article directory

  • Spring6 – (01) case introduces the concept of Spring
    • 1. Environment preparation
      • 1.1 Create a project
      • 1.2 Configure the JDK version
      • 1.3 Configure the Maven environment
      • 1.4 Create a module
    • 2. Simulation development
      • 2.1 Control layer implementation
      • 2.2 Business layer implementation
      • 2.3 Persistence layer implementation
      • 2.4 Test class implementation
      • 2.5 Expand the system
    • 3. Principles of software development
      • 3.1 OCP opening and closing principle
      • 3.1 DIP Dependency Inversion Principle
    • 4. Interface-oriented programming ideas
    • 5. Inversion of Control IoC
    • 6. Spring framework
    • 7. Summary

Spring6 – (01) case introduces Spring concepts

The JDK version supported by Spring 6 is 17

1. Environment preparation

1.1 Create a project

image-20230318085412009

1.2 Configure JDK version

File -> Project Structure

image-20230318090240880

1.3 Configure Maven environment

File -> Settings -> Build, Execution, Deployment -> Build Tools -> Maven

image-20230318085944584

1.4 Create a module

Right-click the project spring6 -> New -> Module

image-20230318090609094

?

2. Simulation development

Delete a user based on the user id

2.1 Control layer implementation

package com.julissa.spring6.controllers;

import com.julissa.spring6.service.UserService;
import com.julissa.spring6.service.impl.UserServiceImpl;

/**
 * Application layer
 */
public class UserController {<!-- -->
    /**
     * Delete user by id
     */
    public void deleteUserById(int userid) {<!-- -->

        UserService userService = new UserServiceImpl();
        userService.deleteUserById(userid);
    }
}

2.2 Business layer implementation

package com.julissa.spring6.service.impl;

import com.julissa.spring6.dao.UserDao;
import com.julissa.spring6.dao.impl.UserDaoImplForMySQL;
import com.julissa.spring6.service.UserService;

/**
 * The implementation class of the business layer UserService
 */
public class UserServiceImpl implements UserService {<!-- -->

    private UserDao userDao = new UserDaoImplForMySQL();
    @Override
    public void deleteUserById(int userId) {<!-- -->
        userDao.deleteUserById(userId);
    }
}

2.3 Persistence layer implementation

package com.julissa.spring6.dao.impl;

import com.julissa.spring6.dao.UserDao;

/**
 * The implementation class of UserDao, which operates the MySQL database
 * @author Julissa
 */
public class UserDaoImplForMySQL implements UserDao {<!-- -->
    @Override
    public void deleteUserById(int id) {<!-- -->
        System.out.println("---connecting to MySQL database---");
        System.out.println("Delete the user whose id is " + id + "");
    }
}

2.4 Test class implementation

package com.julissa.spring.controllers;

import com.julissa.spring6.controllers.UserController;
import org.junit.jupiter.api.Test;

public class TestUserController {<!-- -->
    @Test
    public void test(){<!-- -->
        UserController userController = new UserController();
        userController. deleteUserById(2);
    }
}

Results of the:

image-20230318094723316

It can be seen that UserDaoImplForMySQL mainly connects to the MySQL database for operations.

2.5 Expand the system

If you switch to an Oracle database, you need to provide another UserDaoImplForOracle

package com.julissa.spring6.dao.impl;

import com.julissa.spring6.dao.UserDao;

/**
 * The implementation class of UserDao, which operates the Oracle database
 * @author Julissa
 */
public class UserDaoImplForOracle implements UserDao {<!-- -->

    @Override
    public void deleteUserById(int id) {<!-- -->
        System.out.println("---connecting to Oracle database---");
        System.out.println("Delete the user whose id is " + id + "");
    }
}

Obviously, the above operations are expanding the functions, and a new class UserDaoImplForOracle has been added to cope with changes in the database. Will the changes here cause a chain reaction?

Of course, if you want to switch to the Oracle database, the UserServiceImpl class code needs to be modified

package com.julissa.spring6.service.impl;

import com.julissa.spring6.dao.UserDao;
import com.julissa.spring6.dao.impl.UserDaoImplForMySQL;
import com.julissa.spring6.dao.impl.UserDaoImplForOracle;
import com.julissa.spring6.service.UserService;

/**
 * The implementation class of the business layer UserService
 */
public class UserServiceImpl implements UserService {<!-- -->

    //private UserDao userDao = new UserDaoImplForMySQL();
    private UserDao userDao = new UserDaoImplForOracle();
    @Override
    public void deleteUserById(int userId) {<!-- -->
        userDao.deleteUserById(userId);
    }
}

Modify the code, which violates the OCP opening and closing principle, DIP dependency inversion principle

3. Principles of software development

3.1 OCP opening and closing principle

OCP: It is the most basic principle among the seven software development principles: Open and close principle

  • Open to extension
  • Close for editing

The OCP principle is the core and the most basic, and the other 6 principles serve this principle

What is the core of the OCP principle:

  • As long as you do not modify the previously written code when expanding the system functions, it is in line with the OCP principle. On the contrary, if you modify the previous code when expanding the system, then the design will fail.
  • This is taboo and not allowed. Because once the program that was running normally before is modified, it will lead to a comprehensive retest of the project as a whole. This is quite a cumbersome process. The main reason for the above problems is: the coupling between code and code is too high.

3.1 DIP Dependency Inversion Principle

Dependencies for the example above:

image-20230318100704348

The upper layer is dependent on the lower layer. UserController relies on UserServiceImpl, and UserServiceImpl relies on UserDaoImplForMySQL, which will lead to as long as the changes below, the above will inevitably be implicated (and will be changed later), the so-called affect the whole body .

What is violating the Dependency Inversion Principle:

? Where the upper layer depends on the lower layer, as long as the “lower” is changed, the “upper” will be implicated

What is compliant with the Dependency Inversion Principle:

? The upper layer no longer depends on the lower layer,

The core of the Dependency Inversion Principle:

? Advocate interface-oriented programming, abstract programming, not specific programming, so that the upper layer no longer depends on the lower layer, and the lower layer is changed, and the upper code will not be implicated

What is Dependency Inversion Principle:

? Interface-oriented programming, abstract programming, not concrete programming

Purpose of Dependency Inversion Principle:

? Reduce the coupling degree of the program and improve the expansion ability

Example:

public class UserServiceImpl implements UserService {<!-- -->

    private UserDao userDao = new UserDaoImplForOracle(); // For specific programming, there are specific implementation classes
    
private UserDao userDao;// interface-oriented programming

    @Override
    public void deleteUserById(int userId) {<!-- -->
        userDao.deleteUserById(userId);
    }
}

4. Interface-oriented programming ideas

Some people may think that the above code is already oriented to interface programming:

image-20230318102631694

It is indeed interface-oriented programming

But the creation of the object is: new UserDaoImplForOracle () is obviously not completely interface-oriented programming, or a specific interface implementation class is used.

What is called fully interface-oriented programming? What does it mean to fully comply with the Dependency Inversion Principle?

image-20230318102800404

If the code is written in this way, it can be regarded as completely interface-oriented programming, which is in line with the principle of dependency inversion.

After re-executing the program, you will find:

But in this way, userDao is null, and a null pointer exception will occur during execution.

So we have to solve this problem, to solve the problem of null pointer exception, in fact, to solve two core problems:

  • The first question: who will be responsible for the creation of the object. [That is to say who will come: new UserDaoImplForOracle()/new UserDaoImplForMySQL()]
  • The second question: who will be responsible for assigning the created object to this property. [That is to say, who will assign the object created above to the userDao attribute]

If we solve the above two core problems, we can meet both the OCP opening and closing principle and the dependency inversion principle.

So how to do it? You can use the “inversion of control” programming idea to solve this problem

So what is Inversion of Control?

5. Inversion of Control IoC

Inversion of Control (IoC for short) is a design idea in object-oriented programming, which can be used to reduce the coupling between codes and conform to the principle of dependency inversion.

The core of inversion of control is: Hand over the right to create objects, hand over the management right to the relationship between objects and objects, and let the third-party container be responsible for the creation and maintenance.

What is reversed are two things:

  • Hand over the creation/management rights of objects, no longer use hard-coded methods
  • The management right of the object relationship is handed over, and the hard-coded method is no longer used

Common implementation of inversion of control: dependency injection (Dependency Injection, DI for short)

Inversion of control is an idea, and dependency injection is the concrete realization of this idea.

Dependency injection, what does “dependency” mean? What does “inject” mean?

  • Dependence: the relationship between A object and B object
  • Injection: It is a means by which the A object and the B object can have a relationship
  • Dependency injection: The relationship between A object and B object is maintained by means of injection, and injection includes set injection and constructor injection

image-20230318110036268

Dependency injection DI includes two methods:

  • Set method injection (execute set method to assign value to property)

  • Constructor injection (execute the constructor to assign values to properties)

The Spring framework is a framework that realizes the idea of IoC.

IoC can be considered as a new design pattern, but the theory and time mature relatively late, and it is not included in the GoF. (GoF refers to 23 Design Patterns)

6. Spring Framework

Spring framework is a framework that realizes the idea of IoC. In the Spring framework, it can help us to:

  • Help us new object
  • Assign the new object to the attribute

In other words, Spring framework can help us create objects, and can help us maintain the relationship between objects and objects. for example:

image-20230318103302160

Spring can create a new UserDaoImplForMySQL object, or a new UserDaoImplForOracle object, and can also create a relationship between the new dao object and the service object (generating a relationship is essentially assigning a value to an attribute).

7. Summary

What is the Spring framework?

? The Spring framework is a framework that implements the idea of IoC, and the idea of IoC is the idea of inversion of control.

What is Inversion of Control? To solve what problem?

? Hand over the creation rights of objects and the management rights of objects and the relationship between objects, and let the third-party container be responsible for the creation and maintenance

? Solving the coupling degree problem between codes can reduce the coupling degree between codes and make the code conform to the OCP opening and closing principle and the dependency inversion principle.

What is an inversion?

? Two things are reversed, the right to create/manage objects is handed over, and the right to manage object relationships is handed over.

How to achieve inversion of control?

? Dependency injection

What is dependency injection?

? Dependency is the direct relationship between objects. Injection is a manual way to create a relationship between objects.

How to implement dependency injection?

? Two implementation methods, set injection and constructor injection, set injection is to execute the set method to assign values to attributes, and constructor injection is to execute the construction method to assign values to attributes

Terms

? OCP: open-closed principle (development principle)

? DIP: Dependency Inversion Principle (Development Principle)

? IoC: Inversion of Control (an idea, a new design pattern)

? DI: Dependency Injection (the specific implementation of the idea of inversion of control)