JAVA simulates Spring to implement IoC process (with source code)

Introduction: my senior student has written blog for the first time. If there is something wrong with it, please correct me.

I. Inversion of Control Inversion Control

Traditional development requires new objects, but there are several problems in doing so:

 

    1. It's inefficient and time-consuming to create objects. I want to use objects right away, but the system says that it will take a while to create and initialize objects.  
    2. Object associations, such as: when a user has a department, it is necessary to create a department object if the Department object does not exist.
    3. Code coupling is high

 

So some people put forward the concept of IoC control inversion. Why don't I create it first? If the user wants to use it, I have already created it. Can't the user use it immediately? This is a bit like the rule of law: "don't look for me, I'll find you."

 

IoC is not a technology, but an idea, an important object-oriented programming rule, which can guide us how to design loosely coupled, better programs. Traditional applications are created by us actively within the class, which results in high coupling between the class and the class and is difficult to test. With the IoC container, the control of creating and searching dependent objects is handed over to the container and injected into the composite objects by the container, so the object and the object are loosely coupled, which is also convenient for testing, conducive to functional reuse, and more importantly. It makes the whole architecture of the program very flexible.

 

My personal understanding of IoC is as simple as this:

1) Objects are not created by new, but by reflection.

2) Since it was created beforehand, we have to find a place to put it before using it. Where should we put it? Put it in a Map < String, Object > collection

 

 

II. Some Problems to Consider in the Process of Implementing IoC

How to get the object to be created?

How to convert directory name to class name?

How to convert class names to beanName?

Which classes need to create objects? How to filter out classes that do not need to create objects?

How to store objects in containers?

How to call objects stored in containers?

Design hierarchical structure: high cohesion, low coupling (equivalent to doing one thing, don't write all the functions together)

 

Implementing IoC by Simulating Spring

Here is a simple simulation of user information, which is more complex in practical application, but it is very important to understand the principles.

 

1) architecture diagram

 

 

 

2) Code Structure Diagram

Structural schematics in IDEA (eclipse is similar, I use IDEA):

Each package name and the meaning of the file name (the file name may be inconsistent with some of the file names in the schematic diagram, because the schematic diagram was drawn before, but it does not affect reading, much the same as little):

annotation package: used to store annotations. In this case, the classes that need to create objects are control layer class, business layer class and persistence layer class. All three annotations are needed to filter out classes that do not need to create objects through annotations. Controller annotations are added to the control layer, Service annotations are added to the business layer, Respository annotations are added to the persistence layer; all three annotations are located on the class. Reserve until runtime;

The pojo package: Set up a pojo class with some simple attributes;

dao package: Simulated persistence layer, because this case is a simple example, mainly used for beginners to view, all do not install the database, under normal circumstances, the persistence layer should be connected with the database, no database installed, all by the persistence layer simulated the database;

service package: simulate business layer, business layer calls persistence layer;

controller package: simulation control layer, control layer calls business layer;

Utls package: toolkit;

parse package: Because we adopt hierarchical structure, we should scan and load these components together before using them; now they are all developed for interfaces, which can improve the flexibility of the program, for interface development, and also reflect the polymorphism of JAVA.

The Run file is equivalent to the entry of the entire program.

 

 

4. Case Source Code

1) pojo class (User.java)

 1 package spring.pojo;
 2 
 3 /**
 4  * @Auther: Lin An Jie
 5  * @Date: 2019/9/28 19:28
 6  * @Description:Create pojo objects, simply set properties and get,set,toString methods
 7  */
 8 public class User {
 9     private Integer id;
10     private String name;
11 
12     public Integer getId() {
13         return id;
14     }
15 
16     public void setId(Integer id) {
17         this.id = id;
18     }
19 
20     public String getName() {
21         return name;
22     }
23 
24     public void setName(String name) {
25         this.name = name;
26     }
27 
28     @Override
29     public String toString() {
30         return "User{" +
31                 "id=" + id +
32                 ", name='" + name + '\'' +
33                 '}';
34     }
35 }

 

2) Annotations

    ①Respository.java

 1 package spring.annotation;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 /**
 9  * @Auther: Lin An Jie
10  * @Date: 2019/9/28 19:31
11  * @Description:dao Layer class annotation
12  */
13 
14 @Target(ElementType.TYPE)   // Annotations are added to classes
15 @Retention(RetentionPolicy.RUNTIME) // Retain to runtime
16 public @interface Respository {
17 }

     ②Service.java

 1 package spring.annotation;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 /**
 9  * @Auther: Lin An Jie
10  * @Date: 2019/9/28 19:33
11  * @Description:Business layer annotations
12  */
13 
14 @Target(ElementType.TYPE)
15 @Retention(RetentionPolicy.RUNTIME)
16 public @interface Service {
17 }

      ③Controller.java

 1 package spring.annotation;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 /**
 9  * @Auther: Lin An Jie
10  * @Date: 2019/9/28 19:34
11  * @Description:Control Layer Annotation
12  */
13 
14 @Target(ElementType.TYPE)
15 @Retention(RetentionPolicy.RUNTIME)
16 public @interface Controller {
17 }

3) Persistence Layer (UserDao.java)

 1 package spring.dao;
 2 
 3 import spring.annotation.Respository;
 4 import spring.pojo.User;
 5 
 6 import java.util.ArrayList;
 7 import java.util.List;
 8 
 9 /**
10  * @Auther: Lin An Jie
11  * @Date: 2019/9/28 19:36
12  * @Description:dao Layer to simulate database data
13  */
14 
15 @Respository
16 public class UserDao {
17     // Simulate a query for a record based on the id query
18     public User selectOne(Integer id) {
19         User user = new User();
20         user.setId(id);
21         user.setName("Lin An Jie");
22         return user;
23     }
24 
25     // Simulate queries for all records
26     public List<User> get() {
27         // Use a collection to store all objects
28         List<User> userList = new ArrayList<>();
29 
30         User u1 = new User();
31         u1.setId(6);
32         u1.setName("linanjie");
33         userList.add(u1);
34 
35         User u2 = new User();
36         u2.setId(7);
37         u2.setName("linlin");
38         userList.add(u2);
39         return userList;
40     }
41 
42 
43 }

4) Business layer (UserService.java)

 

 

 1 package spring.service;
 2 
 3 import spring.annotation.Service;
 4 import spring.dao.UserDao;
 5 import spring.pojo.User;
 6 
 7 import java.util.List;
 8 
 9 /**
10  * @Auther: Lin An Jie
11  * @Date: 2019/9/28 19:48
12  * @Description:Business Layer, Getting Data from dao Layer
13  */
14 
15 @Service
16 public class UserService {
17     private UserDao userDao;    // hold dao Layer objects are set to private member variables to be accessed dao Method in Layer (Combination)
18 
19     // Relational binding( set Injection)
20     public void setUserDao(UserDao userDao) {
21         this.userDao = userDao;
22     }
23 
24     // Query a record
25     public User getOne(Integer id) {
26         return userDao.selectOne(id);
27     }
28 
29     // Query all records
30     public List<User> queryAll() {
31         return userDao.get();
32     }
33 }

5) Control Layer (UserController.java)

 1 package spring.controller;
 2 
 3 import spring.annotation.Controller;
 4 import spring.pojo.User;
 5 import spring.service.UserService;
 6 
 7 import java.util.List;
 8 
 9 /**
10  * @Auther: Lin An Jie
11  * @Date: 2019/9/28 19:53
12  * @Description:Control layer, calling business layer
13  */
14 
15 @Controller
16 public class UserController {
17     private UserService userService;    // Setting Business Layer Objects to Private Membership Variables
18 
19     // set Injection, Relation Binding
20     public void setUserService(UserService userService) {
21         this.userService = userService;
22     }
23 
24     // Query a record
25     public User getOne(Integer id) {
26         return userService.getOne(id);
27     }
28 
29     // Query multiple records
30     public List<User> queryAll() {
31         return userService.queryAll();
32     }
33 }

6) Tool class

    ①FileUtil.java

 

 1 package spring.utils;
 2 
 3 import java.io.File;
 4 import java.util.List;
 5 
 6 /**
 7  * @Auther: Lin An Jie
 8  * @Date: 2019/9/28 19:58
 9  * @Description:File Scanning Tool Class
10  */
11 
12 public class FileUtil {
13     // Scan all.class file,Coexist in an array
14     public static List<String> getFileNameList(String dir, List<String> fileNameList) {
15         File file = new File(dir);  // hold string Type conversion to file type
16         File[] files = file.listFiles();    // Traverse through all files in the current path (traverse out: all file names)+All directory names)
17         for (File f :
18                 files) {
19             if (f.isDirectory()) {  // Judging whether the current file is a directory or not, it recursively traverses the contents of the directory
20                 getFileNameList(f.getAbsolutePath(), fileNameList);
21             } else {
22                 fileNameList.add(f.getAbsolutePath());  // Either directory or file, add the file to the array
23             }
24         }
25         return fileNameList;
26     }
27 }

 

     ②CoverUtil.java

 

 1 package spring.utils;
 2 
 3 import java.util.List;
 4 
 5 /**
 6  * @Auther: Lin An Jie
 7  * @Date: 2019/9/28 21:30
 8  * @Description:Unification replaces the path symbol with "/", and the path symbol has "/", "", so there will be no difference after unification.
 9  */
10 public class CoverUtil {
11     // From Deposit All class Documentation fileNameList Each file name (globally qualified name) is taken out of the collection and replaced by a class name (package name)..Class name)
12 
13     /**
14      * @param baseDir      Datum path
15      * @param fileNameList An array of fully qualified names for all files
16      * @return
17      */
18     public static List<String> getClassNameList(String baseDir, List<String> fileNameList) {
19         // Unify the path symbols in the reference path
20         baseDir = baseDir.replace("\\", "/");
21         for (int i = 0; i < fileNameList.size(); i++) {
22             // Get the elements in the array
23             String fileName = fileNameList.get(i);
24 
25             // Unify paths in elements (full set of qualified names)
26             fileName = fileName.replace("\\", "/");
27 
28             // Replace the same benchmark path in the full set qualified name with an empty string
29             fileName = fileName.replace(baseDir, "");
30 
31             // Remove the replaced string.class Suffix
32             int pos = fileName.lastIndexOf(".");
33             fileName = fileName.substring(0, pos);
34 
35             // Replace the path character of the string with“."
36             fileName = fileName.replace("/", ".");
37 
38             // Continue placing the final class name back in the array
39             fileNameList.set(i, fileName);
40         }
41         return fileNameList;
42     }
43 }

      ③BeanNameUtil.java

 1 package spring.utils;
 2 
 3 
 4 /**
 5  * @Auther: Lin An Jie
 6  * @Date: 2019/9/28 23:06
 7  * @Description:Converting className to beanName
 8  */
 9 public class BeanNameUtil {
10     public static String getbeanName(String className) {
11         // Intercept the following class name
12         int pos = className.lastIndexOf(".") + 1;
13         className = className.substring(pos);
14         // The first letter of the class name is lowercase, and the following is unchanged
15         String beanName = className.toLowerCase().charAt(0) + className.substring(1);
16         return beanName;
17     }
18 }

7) Component Scanning

     ①BeanFactory.java

 1 package spring.parse;
 2 
 3 import java.util.List;
 4 
 5 /**
 6  * @Auther: Lin An Jie
 7  * @Date: 2019/9/28 23:26
 8  * @Description:Faced with interface development; need to design an interface
 9  */
10 public interface BeanFactory {
11     public List<String> scan(String dir);
12 
13     public void creat(String baseDir, List<String> fileNameList) throws Exception;
14 
15     public <T> T getObject(String beanName);
16 }

      ②ComponentScan.java

 1 package spring.parse;
 2 
 3 import spring.annotation.Controller;
 4 import spring.annotation.Respository;
 5 import spring.annotation.Service;
 6 import spring.utils.BeanNameUtil;
 7 import spring.utils.CoverUtil;
 8 import spring.utils.FileUtil;
 9 
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14 
15 /**
16  * @Auther: Lin An Jie
17  * @Date: 2019/9/28 22:30
18  * @Description:Scanning all required components and creating objects with reflection, placing objects in containers
19  */
20 public class ComponentScan implements BeanFactory{
21 
22     private static final Map<String, Object> beans = new HashMap<>();
23 
24     // Scan all class file
25     public List<String> scan(String dir) {
26         List<String> fileNameList = new ArrayList<>();
27         FileUtil.getFileNameList(dir, fileNameList);
28         // Traverse to see the contents of the array
29         for (String fileName :
30                 fileNameList) {
31             System.out.println(fileName);
32         }
33         return fileNameList;
34     }
35 
36     // Create objects from annotations by reflection and place them in containers
37     public void creat(String baseDir, List<String> fileNameList) throws Exception {
38         List<String> classNameList = CoverUtil.getClassNameList(baseDir, fileNameList);
39 
40         // Traverse the class name array to see the content and create objects based on whether there are annotations
41         for (String className : classNameList) {
42             String beanName = "";
43             Class<?> clazz = Class.forName(className);
44             // Get annotations on classes
45             Controller ca = clazz.getAnnotation(Controller.class);
46             Service sa = clazz.getAnnotation(Service.class);
47             Respository ra = clazz.getAnnotation(Respository.class);
48 
49             // If the comment is not empty, create the object
50             if (ca != null || sa != null || ra != null) {
51                 Object obj = clazz.newInstance();
52 
53                 /*Store objects in containers. Containers are Map key-value pairs. Values are objects. Key is too complex to be represented by className. ClassName is converted into beanName.
54                   className Form: spring.pojo.User; beanName form: user; so you need to write a transformation method
55                  */
56                 beanName = BeanNameUtil.getbeanName(className);
57 
58                 // Store objects in containers
59                 beans.put(beanName, obj);
60             }
61             System.out.println(className + " | " + beanName);
62         }
63 
64         // View objects stored in containers
65         System.out.println("\n The objects stored in the container are:");
66         for (String key : beans.keySet()) {
67             System.out.println(beans.get(key));
68         }
69     }
70 
71     // Getting objects from containers
72     public <T> T getObject(String beanName){
73         return (T) beans.get(beanName);
74     }
75 }

8) procedure entry (Run.java)

 1 package spring;
 2 
 3 import spring.controller.UserController;
 4 import spring.dao.UserDao;
 5 import spring.parse.BeanFactory;
 6 import spring.parse.ComponentScan;
 7 import spring.pojo.User;
 8 import spring.service.UserService;
 9 
10 import java.util.List;
11 
12 
13 /**
14  * @Auther: Lin An Jie
15  * @Date: 2019/9/29 12:53
16  * @Description:Program entry
17  */
18 public class Run {
19     public static void main(String[] args) throws Exception {
20         // Faced with interface development, it embodies polymorphism (upward modeling)
21         BeanFactory context = new ComponentScan();
22 
23         // Scan all first class file
24         System.out.println("First step,Scan all of the current home directories class Document:");
25         // You can't write the path to death, you can API Access path
26         String baseDir = Run.class.getResource("/").getPath().substring(1);
27         String packageDir = Run.class.getPackage().getName();
28         String dir = baseDir + packageDir.replace(".", "/");
29         List<String> fileNameList = context.scan(dir);
30 
31         System.out.println("\n Step 2: Achieve className,And use beanName Store objects in containers:");
32         context.creat(baseDir, fileNameList);
33 
34         System.out.println("\n The third step is business processing:");
35         // Out-of-service new To create an object, you need to get the object from the container
36         UserController userController = context.getObject("userController");
37         UserService userService = context.getObject("userService");
38         UserDao userDao = context.getObject("userDao");
39 
40         // Relation injection, invocation set Method
41         userController.setUserService(userService);
42         userService.setUserDao(userDao);
43 
44         System.out.println("Query a record:");
45         User user = userController.getOne(1);
46         System.out.println(user);
47 
48         System.out.println("Query all records:");
49         List<User> users = userController.queryAll();
50         for (User u : users) {
51             System.out.println(u);
52         }
53     }
54 }

V. Operation results

 

 

 

 

 

 

This is the content shared in this issue. You can learn from each other. Later, you will write Spring simulation to implement DI (the principle is almost the same).

Keywords: Java Spring Database Programming

Added by monezz on Mon, 07 Oct 2019 15:08:19 +0300