Understanding java annotation two

I wrote the first note about understanding java, but I guess everyone will not care too much: Isn’t it just some annotation concepts? However, I still feel that the foundation is very important. When I first started to understand annotations, I was puzzled: Just write a name for an annotation, and the code will know what you want to do? Think of it as artificial intelligence! Then I asked the other friends, they were also half-knowledgeable and at a loss. Later, I went to see the explanations and slowly guessed a little bit.

An annotation, which looks tall, can perform parameter verification, data conversion, method processing filtering processing, etc., in fact, it is just implemented silently in the background through reflection, and these codes are really unnamed logical processing. hero!

If you have used the java framework for a period of time, you will be more or less exposed to the use of annotations, and you are familiar with the effects of some annotations. Maybe more people are using Spring Family Bucket, @RestController,@ResponseBody,@RequestBody,@Autowired,@Resource,@RequestParam,@Service,@Component,@Repository,@Mapper,@Configuration, are all very familiar with It's also very convenient.

However, I don’t understand the principle very well. Even if I open these comments at all, it may be a big mess. I don’t bother to read it. It is really a headache to read these things rashly. I am not able to explain this clearly. I will talk about it today. Getting started, if you are interested in the follow-up, you can look at the in-depth analysis of the Spring source code to understand the implementation of these annotations.

I would like to mention here, some novices may make such mistakes.

@RestController("/demo")
public class DemoController {

    @PostMapping("test")
    public DefaultResponse getInfoList(@RequestBody RequestVo requestVo){
        return  null;
    }
}
@Data
public class RequestVo {

    private  String uuid ;

    private Integer minAge;

    private String maxAge;

    // 学校id必须不为空

    @NotNull(message = "学校id不能为空")
    private String schoolId;

}

As you can see, this is a simple Spring request receiving process that cannot be simpler. The json input parameter is directly converted to the object RequestVo through @RequestBody, and the verification schoolId cannot be null is added at the same time.

Of course, my careful friends have discovered that, in fact, this check @NotNull(message = "School id cannot be empty") does not work. The reason is simple. As I said before, annotations are not artificial intelligence and cannot be identified by themselves. , And this @NotNull is not combined with @RequestBody, and it is not directly embedded in Spring, so it is impossible to automatically verify it. I don’t know if any of my friends have encountered such a problem. I was wondering when the bug was raised in the test, but it is really hard to find out without careful testing. Haha, adjust the atmosphere.

In fact, when you open this @NotNull, you can find that its use is combined with another annotation, that is @Valid. Only by writing in this way can the null check be truly done.

   @PostMapping("test")
    public DefaultResponse getInfoList(@Valid @RequestBody RequestVo requestVo){
        return  null;
    }

Of course, this @Valid encapsulation is very classic. If the same interface is requested multiple times, different filtering rules can be implemented as needed. If you are interested, you can check it out~ (mainly in the group definition processing in @NotNull)

Pulled a bit far, and started to get to the point.

Write a simple annotation below to get it.

Annotation color:

package com.example.annotion;

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Color {
    String value();
}

This is a very common annotation, that is color, value indicates the value of the color

Fruit Apple, fruit naturally has a color, for example, if you hear an apple, you may know it, oh, the color is red:

package com.example.vo;

import com.example.annotion.Color;
import lombok.Data;

@Data
public class Apple {

    @Color(value = "red")
    private String name;

    private Double price;

}

Obtaining annotations:

package com.example.demo;

import com.example.annotion.Color;
import com.example.vo.Apple;

import java.lang.reflect.Field;

public class MyTest {
    public static void main(String[] args) throws Exception{

        // 加载类
        Class<?> appleClass = Class.forName("com.example.vo.Apple");
       //这样也可以  Class<? extends Apple> appleClass = new Apple().getClass();
        Field[] fields = appleClass.getDeclaredFields();
        for (Field field:fields) {
            field.setAccessible(true);
            Color color = field.getAnnotation(Color.class);
            if (color != null){  // 说明有Color 的注解
                System.out.println("apple 的颜色是:" + color.value());
                System.out.println(" 属性的名称是: " + field.getName());
            }
            break;
        }
        System.out.println("this is end.....");
    }
}

Output result:

Connected to the target VM, address: '127.0.0.1:58458', transport: 'socket'
apple 的颜色是:red
 属性的名称是: name
this is end.....
Disconnected from the target VM, address: '127.0.0.1:58458', transport: 'socket'

Process finished with exit code 0

Of course, when you see this example, you must feel ---trash, such a naive acquisition operation, I will too!

Yes, the analysis of this annotation is very basic, and it may be written by anyone who has learned a little Java.

However, the principle remains the same, and the basics are often very important and critical, and you can easily overlook a lot if you don't know it.

Let me talk about an annotation processing used in my previous work:

A project needs to upload files in many places, and then save the file information. A page comes from the front end, and there may be many file types that need to be saved, such as ImageVo. Of course, this must not be processed one by one. It is too cumbersome, and this kind of saving operation that has little business relationship should be unified encapsulated to be the most reasonable .

Of course, you can take out the parameters every time and pass them to a method. But, do you have to take the parameters for each request? And what if there are more parameter levels? You have to add judgments and so on,

Of course, this can be handled very well with annotation + reflection!

Try to write it out this week. I was too lazy before. It is necessary to settle something, O(∩_∩)O haha~

 

 

Guess you like

Origin blog.csdn.net/zsah2011/article/details/105397010