03 – create springboot project based on idea and do entry analysis

Time:2020-11-30

Background analysis of spring boot

Java EE application system has been criticized by developers for its heavy configuration, low development efficiency, high difficulty of tripartite integration and complex deployment process. Even if spring is used as a lightweight resource integration framework, it still needs a lot of manual dependency management and complex XML configuration (which is often not prompted). What’s more, the software ecological application has also formed a certain scale, and the system architecture is leaping from single architecture, distributed architecture to microservice architecture. With the change of the whole architecture system, the requirements of enterprises for technology are also changing. Nowadays, enterprises pay more attention to the technology out of the box, the deep integration of technology in the ecosystem, and the lightweight operation and maintenance. Thus spring boot was born.

What problems does spring boot solve

Spring boot is a new Java software development framework provided by pivot team (many people now understand it as a scaffold), which is designed to simplify the initial construction and development process of spring projects. The framework uses specific annotation to configure, so that developers no longer need a lot of XML configuration. No more manual dependency management is required. Spring boot is based on the concept of rapid build. It hopes to become a leader in the booming field of rapid application development through the way of agreement over configuration and out of the box.

What are the core key features of spring boot

  • Start dependency.
  • Auto configuration.
  • Actor – monitoring.
  • Embedded services (tomcat, jetty).

Springboot project creation

Create module

Create a project module based on idea, the module name is 04 springboot start, the group ID and package name are com.cy As shown in the figure:
03 - create springboot project based on idea and do entry analysis
Fill in the module information, as shown in the figure:
03 - create springboot project based on idea and do entry analysis
Select the module version of the project, and you do not need to manually add any dependencies, as shown in the figure below:
03 - create springboot project based on idea and do entry analysis
Fill in the module name and complete the module creation, as shown in the figure
03 - create springboot project based on idea and do entry analysis

Project structure analysis

After the project module is created, its code structure is analyzed, as shown in the figure

03 - create springboot project based on idea and do entry analysis

Analysis of springboot project startup

Start the entrance

In the springboot project, the class described by the springbootapplication annotation is the startup entry class, for example:

package com.cy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {//Application.class
  public static void main(String[] args) {//Main Thread
    SpringApplication.run(Application.class, args);
  }
}

Summary analysis of startup process

The simple initialization process of springboot project is shown in the figure below:

03 - create springboot project based on idea and do entry analysis

What is done at the bottom during the startup process is described as follows:
1) Load classes based on configuration (read the class at the specified location to memory through classloader → read the underlying class from disk to memory through thread call IO).
2) Analyze the class (create bytecode object class type, and get the configuration information through reflection).
3) Stores configuration information (with the help of beandefinition objects) for objects that specify configuration (such as described by spring specific annotations).
4) Based on the configuration of class in beandefinition object, the instance of class (bean object) is built to manage bean object.

Springboot quick start analysis

Business description

In the project module, define a class named defaultcache, and then hand this class of objects to spring to create and manage. Finally, the example of class is analyzed by unit test.

API design analysis

Based on the business description, the API and relationship are designed, as shown in the figure

03 - create springboot project based on idea and do entry analysis

Code writing and running

Based on business and API design, the code is written as follows:

Step 1: define the defaultcache class

package com.cy.pj.common.cache;
import org.springframework.stereotype.Component;
/**
 *The @ Component annotation describes the class, indicating that this class is managed by the spring framework.
 */
@Component
public class DefaultCache {
}

Step 2: define the defaultcachetests unit test class

package com.cy.pj.common.cache;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@SpringBootTest
public class DefaultCacheTests {
    /**
 *The properties described by the @ Autowired annotation are injected (assigned values) by the spring framework according to certain rules
 *What is the assignment process like?
 *1) dependency lookup? What are the search rules? )
 *2) dependency injection? What kind of technology is needed
 */ @Autowired
 private DefaultCache defaultCache;
    @Test
 void testDefaultCache(){
        System.out.println(defaultCache.toString());
        //FAQ? Who created the object referenced by the defaultcache variable and where was it stored? bean pool
 }
}

Step 3: run the unit test class for application analysis
03 - create springboot project based on idea and do entry analysis

Start and run the unit test method and test its output results
1) The construction of bean object in springboot project.
2) Get bean object in springboot project.

Bug analysis during operation

  • The bean type cannot be found, as shown in the figure:

03 - create springboot project based on idea and do entry analysis
03 - create springboot project based on idea and do entry analysis

  • Null pointer exception (NullPointerException NPE), as shown in the figure:

03 - create springboot project based on idea and do entry analysis

Analysis of object characteristics in springboot project

preparation

Step 1: create a project module, such as 05 springboot features, as shown in the figure
03 - create springboot project based on idea and do entry analysis

Step 2: add the business class objectpool. The code is as follows:

package com.cy.pj.common.pool;
@Component
Public class objectpool {// assume that this object is an object pool
    Public objectpool() {// suppose the project startup class is run, and this construction method is executed, indicating that such an object has built.
      Systemd.out.println("ObjectPool()")
    }
}

Thinking: what are the characteristics of general pool objects?
1) In the JVM memory will open up a relatively large space.
2) Store some objects in this space (think about what storage structure to store – array, linked list, hash table).
3) The reusability of objects in memory is realized based on the design idea of “sharing element pattern”.

Step 3: define the unit test. The code is as follows:

package com.cy.pj.pool;
import com.cy.pj.common.pool.ObjectPool;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ObjectPoolTests {

    @Autowired
    private ObjectPool objectPool01;
    @Autowired
    private ObjectPool objectPool02;
    @Test
    void testObjectPool01(){
       System.out.println(objectPool01==objectPool02);
    }
}

Delay loading

Now, let’s think about a question. For the objectpool class, if the pool object will not be used temporarily after the project is started, is it necessary to create it (it will be created by default)? We know it’s not necessary because it takes up memory. How can I not create such an object at startup? With the help of the delay loading feature provided by spring framework. For example, we can use the @ lazy annotation to describe the class that needs to be delayed loaded. The code is as follows:

package com.cy.pj.common.pool;
@Lazy
@Component
Public class objectpool {// assume that this object is an object pool
    Public objectpool() {// suppose the project startup class is run, and this construction method is executed, indicating that such an object has built.
      Systemd.out.println("ObjectPool()")
    }
}

At this point, we run the startup class again to check whether the objectpool object has been created. If not, it indicates that the delayed loading has taken effect. At this point, let’s summarize what objects are suitable for using the lazy load feature? Large objects, rarely used (after the project started, temporarily unavailable) objects.
Note: lazy loading does not mean delaying the loading of a class, but does not create an instance of the class temporarily at startup. If you want to see whether the class in memory is loaded, you can check it through the JVM parameter, which is – XX: + traceclassloading.

Object scope analysis

In the actual project, some objects in memory may have to be repeatedly applied many times, and some objects may not be used up again, or the application times are very few. For objects that are often used repeatedly, I can consider storing them in the pool (for example, handing them over to the spring framework for management). For objects that are rarely used, they do not need to be put into the pool. After they are used up, they can be destroyed by themselves. In order to design and manage such objects in spring project, we provide the support of scope feature

package com.cy.pj.common.pool;
@Scope("singleton")
@Lazy
@Component
Public class objectpool {// assume that this object is an object pool
    Public objectpool() {// suppose the project startup class is run, and this construction method is executed, indicating that such an object has built.
      Systemd.out.println("ObjectPool()")
    }
}

In the above code, we use the @ scope annotation to describe the class, which is used to specify the instance scope of the class. If you do not write @ scope, it is the singleton scope by default. This scope will be used in conjunction with the delay load (@ lazy) feature. It means that an instance of this class can be created and stored in the spring container (bean pool) when necessary. If necessary, it can be taken from the pool to realize the reuse of objects. If some objects are applied for a very few times, you can consider not putting them into the pool, and then use the @ scope (“prototype”) scope to describe the class, so that when such objects need to be created and when they are used up, when they are not accessible, they can be directly destroyed by the GC system.

Object life cycle method

Every object in the program has a life cycle. The process of creating, initializing, applying and destroying objects is called the life cycle of objects. Some methods to be executed after the object is created to be initialized and destroyed after the application is completed. We can call them lifecycle methods. But not every object defines a lifecycle method. In practical projects, some pool objects usually define such life cycle methods (such as connection pool). How to identify such a method in the spring project? The @ postconstruct and @ predestroy annotations are usually used to describe specific methods, such as:

package com.cy.pj.common.pool;
@Scope("singleton")
@Lazy
@Component
Public class objectpool {// assume that this object is an object pool
    public ObjectPool(){
      Systemd.out.println("ObjectPool()")
    }
    @PostConstruct
    public void init(){
       System.out.println("init()");
    }
    @PreDestroy
    public void destory(){
     System.out.println("destory()");
    }
}

Among them:
1) The method described in the @ postconstruct annotation is the life cycle initialization method, which is executed after the object is built
2) The method described in the @ predestroy annotation is a lifecycle destruction method. If the object of this method is stored in the spring container, the lifecycle destruction method will be executed before the object is removed from the spring container (prototype scope objects do not execute this method)

Analysis of dependency injection process in springboot project

In the springboot project, if there is a certain dependency relationship between classes, how does spring implement dependency injection? Now we will make an analysis through a case.

preparation

Step 1: create a project module, as shown in the figure:
03 - create springboot project based on idea and do entry analysis
Step 2: start the running project and check whether it can be started successfully

Case design and analysis

In order to better understand the underlying injection mechanism of spring framework, the case API is designed, as shown in the figure:

03 - create springboot project based on idea and do entry analysis

In this case, a cache interface type property is defined in the unit test class cachetests, and then the spring framework completes the injection of the cache type attribute value.

Code writing and test analysis

The first step is to define the cache interface code

package com.cy.pj.common.cache;
public interface Cache {
 
}

Step 2: define the cache interface implementation class softcache. The code is as follows:

package com.cy.pj.common.cache;
 
@Component
public class SoftCache implements Cache{

}

Step 3: define the cache interface and implement the weakcache class. The code is as follows:

package com.cy.pj.common.cache;
 
@Component
public class WeakCache implements Cache{

}

Step 4: define the cachetests unit test class. The code is as follows:

package com.cy.pj.common.cache;
import org.junit.jupiter.api.Test;

@SpringBootTest    
public class CacheTests {
    @Autowired
    @Qualifier("softCache")
    private Cache cache;
    
    @Test
    public void testCache() {
        System.out.println(cache);
    }
} 

Where @ Autowired is defined by the spring framework to describe properties or related methods (such as constructor) in a class. When the spring framework runs a project, if it finds that there are properties or methods described with @ Autowired annotation in the bean object managed by it, it can assign a value (DI) to the attribute according to the specified rules.

Step 5: run cachetests to detect the output results and understand the injection rules based on the results.

Bug analysis in the process of writing and testing

  • Dependency injection exception, as shown in the figure:

03 - create springboot project based on idea and do entry analysis
03 - create springboot project based on idea and do entry analysis
Solution: assign a value to a property according to the specified rule (DI): first, check whether there is an object in the container that matches the type of the property or method parameter. If there is one and only one object, it will be injected directly. Secondly, if more than one is detected, it will search whether there is a matching object according to the property or method parameter name described by @ Autowired. If there is one, it will be injected directly, otherwise an exception will be thrown. Finally, if we have a specific requirement, we must inject objects with the specified type and name as the specified name. We can also use the @ qualifier annotation to describe its properties or parameters (this annotation must be used with the @ Autowired annotation).

Summary

This section is the introduction chapter of springboot technology. It mainly describes the compilation, characteristics and dependency injection rules of bean objects in spring under the springboot project. I hope that through the explanation in this section, students can understand why we should give objects to spring management, what advantages spring management objects have, and how we should configure these objects in springboot projects.

Recommended Today

Ajax simple asynchronous communication example analysis

This paper introduces the method of Ajax simple asynchronous communication. Share with you for your reference. The specific analysis is as follows: client:Make an empty request to the server. The code is as follows: <html> <head> <title>XMLHttpRequest</title> <script language=”javascript”> var xmlHttp; function createXMLHttpRequest(){ if(window.ActiveXObject) xmlHttp = new ActiveXObject(“Microsoft.XMLHTTP”); else if(window.XMLHttpRequest) xmlHttp = new XMLHttpRequest(); } […]