Chapter 2: basic configuration of Spring Boot2.x

Keywords: Java SpringBoot Spring SQL

Chapter 2: basic configuration of Spring Boot2.x (in continuous update Updated February 27)

Summary of this chapter

  • What is annotation?
  • What are the core annotations of Spring Boot2.x?
  • What is auto configuration?
  • How can we extend our application with auto configuration feature?
  • Let's take a small example and explain the automatic configuration?

reminder:
Supporting code: https://gitee.com/guduwuhen/springboot2-lesson Next: lesson2-1

Article directory

2.1 let's talk about the notes first

2.1.1 what are the notes?

Official definition: Annotation (also known as metadata) is a special modifier applied to classes, methods, parameters, variables, constructors, and package declarations. It is a tool chosen by JSR-175 standard to describe metadata. Generally speaking, it provides a formal way for us to add information to the code, so that we can easily use the data at a later time.

In fact, annotation itself has no function. In short, there is no difference between annotation and annotation, and the reason it works is: annotation interpretation class, that is, the specific class for annotation interpretation. In this way, it's still more abstract. Let's use an example to explain it. Let's write an annotation by ourselves, and we'll have a deeper understanding.

2.1.2 write a note by hand

In order to better understand the annotation, we will explain some code and debug it when we write the instance. Please be sure to prepare the spring boot development environment (refer to the last section of the previous chapter), let's do it together.

Instance function: add database table annotation by entity class and column annotation by variable in class, and generate query sql statement by entity class object and reflection mechanism. This function is similar to the idea of hibernate.

2.1.2.1 write annotation class

  1. Create package: com.binge.springboot.lesson21.annotation
  2. And create two annotation classes, Mytable and MyColumn, under this package

Tip: create annotation tips.
When creating a class, select the annotation type in the pop-up dialog box, as shown in the following figure

Create interface class, enumeration class and select the response type.

The generated code is as follows:

public @interface Mytable {
}

From the generated code, we can see that the class definition of the annotation is similar to the interface, and the difference is that there is an @ symbol in front of the @ interface. Perhaps you will ask, is such an annotation finished? Of course not. Let's go on to the properties of annotations.

2.1.2.2 annotation attributes

Annotation attributes are also called member variables. Annotation has only member variables and no methods. The member variable of annotation is declared in the form of "method without parameter" in the definition of annotation. Its method name defines the name of the member variable, and its return value defines the type of the member variable.

There are restrictions on the types of data that can be used within the annotation, as follows:

All basic types (int, float, boolean, etc.)
String
Class
enum (@ Retention property of type enumeration)
Annotation
Array of the above types (@ Target array with attribute type of enumeration)

The compiler also has constraints on the default values of properties. First, a property cannot have an indefinite value. That is, the property either has a default value or provides the value of the property when using annotations. For properties of non basic types, whether declared in source code or defined as default in annotation interface, null cannot be used as their value. Therefore, in order to avoid this constraint, we need to define some special values, such as empty string or negative number, to indicate that a property does not exist.

2.1.2.3 composition of notes

J2SE 5.0 provides four meta annotations in java.lang.annotation, specifically for other annotations:

  • @Documented – whether annotations will be included in JavaDoc
  • @Retention – when to use this annotation
  • @Target? – where are annotations used
  • @Inherited - whether subclasses are allowed to inherit the annotation

@Documented – a simple Annotations tag that indicates whether to add annotation information to a java document.

@Retention – defines the lifecycle of the annotation.

  • RetentionPolicy.SOURCE: discarded during compilation. These annotations are no longer meaningful after compilation, so they don't write bytecode. @Override,@SuppressWarnings belong to this type of annotation.
  • RetentionPolicy.CLASS: discarded when class is loaded. Useful in bytecode file processing. Annotations use this method by default.
  • RetentionPolicy.RUNTIME: the annotation is never discarded, and is retained during runtime, so the information of the annotation can be read using reflection mechanism. Our custom annotations usually use this way.

@Target – indicates where the annotation is used. If not explicitly stated, the annotation can be placed anywhere. Annotations can be used for packages, types, type members, method parameters, and local variables such as loop variables, catch parameters. Target is used in the declaration of annotation type to clarify the decorated target. The value (ElementType) is:

  • Elementtype.annotation'type can be applied to annotation types.
  • ElementType.CONSTRUCTOR can be applied to constructors.
  • ElementType.FIELD can be applied to fields or properties.
  • Elementtype.local'variable can be applied to local variables.
  • ElementType.METHOD can be applied to method level annotations.
  • ElementType.PACKAGE can be applied to package declarations.
  • ElementType.PARAMETER can be applied to the parameters of a method.
  • ElementType.TYPE can be applied to any element of a class.

Add the following meta annotation to our annotation class: Mytable annotation works on the class and always works, and MyColumn annotation works on member variables and always works.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mytable {
    String name() default "";
}

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyColumn {
    String name() default "";
}

2.1.2.4 annotation usage class

Then we create the annotation using class: User.java, which is a Java bean using annotations. Here we use our custom annotation @ Mytable

package com.binge.springboot.lesson21.entity;

import com.binge.springboot.lesson21.annotation.MyColumn;
import com.binge.springboot.lesson21.annotation.Mytable;

/**
 * @Title: User.java
 * @Package com.binge.springboot.lesson21.entity
 * @Description: User entity class
 * @author: binge
 * @date 2020/2/27
 * @version V1.0
 */

@Mytable("user")
public class User {
    @MyColumn("user_id")
    String userId;  	//User ID

    @MyColumn("user_name")
    String userName;	//User name

    @MyColumn("password")
    String password;	//User password
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

2.1.2.5 annotation and interpretation

With the following class, the two annotations we created have practical significance. The idea of this class is:

  1. We will judge whether a class has added two annotations that we defined
  2. Then get the parameter value of the annotation and use it

The notes in the code clearly indicate the use of the notes. The codes are as follows:

package com.binge.springboot.lesson21.service;

import com.binge.springboot.lesson21.annotation.MyColumn;
import com.binge.springboot.lesson21.annotation.Mytable;
import com.binge.springboot.lesson21.entity.User;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Title: UserService.java
 * @Package com.binge.springboot.lesson21.service
 * @Description: User business
 * @author: binge
 * @date 2020/2/27
 * @version V1.0
 */

public class UserService {
    /**
     * Method of generating query SQL statement by user object
     * @param user  User object
     * @return Generated sql statement
     */
    public static String createSql(User user){
        StringBuffer sb = new StringBuffer();
        //Get the class object of the user through reflection
        Class cla = user.getClass();
        //Judge whether some annotation has been added. Here, judge whether Mytable annotation has been added
        boolean hasAnnotation = cla.isAnnotationPresent(Mytable.class);
        //If no annotation is added, it will be returned directly. Because no annotation is added, sql statement cannot be generated
        if(!hasAnnotation){
            return null;
        }
        //If an annotation is added, cast this annotation type to Mytable
        Mytable mytable = (Mytable)cla.getAnnotation(Mytable.class);
        //This is the parameter passed in to annotate the User class
        String tableName = mytable.value();
        //The next step is to use the reflection mechanism to traverse the variables of the class to generate splicing sql statements
        sb.append("select * from ").append(tableName).append(" where 1=1 ");
        Field[] fields = cla.getDeclaredFields();
        for (Field field : fields){
            //Determine whether the field is annotated with MyColumn
            hasAnnotation = field.isAnnotationPresent(MyColumn.class);
            if(!hasAnnotation){
                return null;
            }

            //The getXXX method will be generated here, and then the value of the field will be obtained by using the reflection mechanism
            String fieldName = field.getName();
            String methodName = "get" + fieldName.substring(0,1).toUpperCase()
                    + fieldName.substring(1);

            //This variable stores the value of each variable
            //This part of code uses reflection mechanism to get the value of each variable
            Object fieldValueObj = null;
            try{
                Method method = cla.getMethod(methodName);
                fieldValueObj = method.invoke(user);
            }catch (Exception e){
                e.printStackTrace();
            }

            //Get the parameter name configured on the column, which is generally the field name of the database
            MyColumn myColumn = (MyColumn)field.getAnnotation(MyColumn.class);
            String colName = myColumn.value();

            //Fields and values of Splicing Database
            sb.append(" and ").append(colName).append("=").append(fieldValueObj);
        }

        //Return the spliced sql
        return sb.toString();
    }

    public static void main(String[] args) {
        //Create a user object and only set the value of some variables
        User user = new User();
        user.setUserId("12");
        user.setUserName("binge");
        String sql = UserService.createSql(user);
        System.out.println(sql);
    }
}

Running this class, you can see the following effect in the console:

Tip: annotation with reflection
1) Only when it is defined as RetentionPolicy.RUNTIME can we get the annotation through annotation reflection.
2) Get CLA and field objects through reflection, and then get annotation values through cla.getAnnotation(Mytable.class) and field.getAnnotation(MyColumn.class) methods
3) Then implement some business logic according to the annotation value

2.1.3 summary of notes

Usefulness:

  1. Generate documents. This is the most common and the first annotation provided by java. Commonly used ones are @ param @return, etc. (we used them in the annotation)
  2. Track code dependency and implement the function of replacing configuration file. (the extensive use of spring annotations can simplify configuration files)
  3. Format checking at compile time. For example, @ override is placed in front of a method. If this method does not override a superclass method, it can be checked at compile time

Advantage:

  1. Save in class file to reduce maintenance cost.
  2. No tool support, no parsing required.
  3. The correctness can be verified at compile time, and error checking becomes easy.
  4. Improve development efficiency.

Disadvantages:

  1. If you want to modify the configuration item, you have to modify the Java file and recompile the packaged application.
  2. The configuration item is encoded in Java file, which has poor scalability.

Through this chapter, do you have a certain understanding of annotations? Generally speaking, different annotations have different functions. Under the spring boot framework, some feature annotations are added to facilitate development and deployment. Later, we will explain some core annotations of spring boot.

2.2 spring boot core annotation

2.2.1 @SpringBootApplication

Published 33 original articles, won praise 7, visited 1388
Private letter follow

Posted by 14zero on Thu, 27 Feb 2020 02:01:55 -0800