Want to write your own framework? Can't write Java annotations

 

It’s cool to use comments for a while, and always cool

After Java back-end development entered the spring family bucket era, the development of a microservice that provides a simple addition, deletion, modification, and checking interface is as simple as playing mud. The operation is fierce, and when I look back at the code, I add a bunch of annotations: @Controller @Autowired @Value, annotation-oriented programming has become an indispensable operation for everyone.

Imagine that if there is no comment, Java programmers can cry: sob:

Since annotations are so important and so cool to use, do you know the implementation principle of annotations? I guess you will only use annotations and not write annotations yourself (manually funny).

Well, the following content takes everyone to write a comment from scratch, and unveil the mystery of the comment.

It turns out that the annotation is not mysterious

An annotation is a mark or a special annotation in the vernacular. If there is no operation to parse these marks, it is nothing.

The annotation format has its own special syntax like a class or method, which will be described in detail below.

How to parse the annotation? This requires the powerful reflection function of Java. Everyone should have used reflection. You can get various information of this class, such as member variables, methods, etc., through the class object. Can the annotation mark be obtained through reflection? of course.

Therefore, the principle of annotation is actually very simple. In essence, the annotation mark is dynamically obtained through the reflection function, and then different operations are performed according to different annotations. For example, @Autowired can inject an object to assign a variable.

Seeing this is not very restless, come on and write a comment for yourself.

Make a rocket, write a note by yourself

To make it easier for everyone to understand, here is a scenario: online education is on fire. The manager asked me to write a module to implement student information management functions. Considering the distributed concurrency problem, the manager asked me to add distributed locks.

The manager asked me how many days can I get it done? I said at least 3 days. If the brain fills in the following code:

Before using annotations

After the manager left, I was thinking, can I just spend one day to finish writing, and the remaining two days for blogging? Suddenly the inspiration came, I can extract the repetitive code logic and use annotations to implement it and save the code, haha, hurry up and write.

After using annotations, the whole method is much more refreshing. Miss HR praised me for writing well.

After using annotations

The code has been written on the library, and now I am paddling and blogging. Is it very simple, elegant, and awesome? How to do it? It is divided into three steps: 1 open the refrigerator door, 2 put the elephant in, and 3 close the refrigerator door. Okay, far away, everyone will look down.

The first step is to define an annotation

Three major components of annotation

An annotation can be simply broken down into three parts:

Part 1: Annotation

The definition of annotation is a bit similar to interface, except that an @ symbol is added to the previous one, this must not be omitted.

Part 2: Annotate variables

The syntax of annotation variables is a bit similar to the method defined in the interface, with a pair of parentheses after the variable name, the difference is that there can be default values ​​after the annotation variable. In addition, the return value can only be a Java basic type, String type or enumeration type, not an object type.

Part 3: Meta-annotation

To put it bluntly, meta-annotation is an annotation to annotate annotations. Isn't it a bit dizzy? This kind of annotation is built in JDK in advance and can be used directly. It doesn’t matter if you don’t understand it well. There are not many, there are only 4 in total. Let’s memorize it: @Target @Retention @Documented @Inherited

  • Target annotation

Used to describe the scope of the annotation, that is, where the modified annotation can be used.

Annotations can be used to modify packages, types (classes, interfaces, enumerations, annotation classes), class members (methods, construction methods, member variables, enumeration values), method parameters and local variables (such as loop variables, catch parameters), Using @Target when defining an annotation class can make it clearer which objects it can be used to modify. The specific value range is defined in the ElementType.java enumeration class.

For example, the Redis lock annotations we wrote above can only be used for methods.

  • Retention annotation

It is used to describe the time range of the annotation retention, that is, the life cycle of the annotation. Three periods are defined in the RetentionPolicy enumeration class:

public enum RetentionPolicy { 
    SOURCE, // source file reserved 
    CLASS, // reserved during compile time, default value 
    RUNTIME // reserved during runtime, annotation information can be obtained through reflection 
}

Like the well-known @Override annotation, it can only remain in the source file, and the annotation disappears after the code is compiled. For example, the Redis lock annotations we wrote above are retained until the runtime, and information can be obtained through reflection during runtime.

  • Documented annotation

It is used to describe whether to keep the annotation information when using the javadoc tool to generate the help documentation for the class. It is very simple and not much explanation.

  • Inherited annotation

The annotation modified by the Inherited annotation has inheritance. If the parent class uses the annotation modified by @Inherited, its subclasses will automatically inherit the annotation.

Ok, we have defined the annotation in this step, but how does this annotation work? Then look.

The second step is to implement the business logic of the annotation

In the first step, we found that there is no business logic in the defined annotation (@EnableRedisLock), only some variables. Don’t forget that our annotation is to enable the Redis distributed lock function. Then how does this annotation implement locking and What about the lock release function? This requires us to use the powerful function of reflection.

 Annotated operation

With the help of the aspect function, the EnableRedisLock annotation is used as a point of contact. As long as this annotation is marked on the method, the code logic here will be automatically executed.

After getting the annotation object through the reflection mechanism, you can execute the common logic of locking and unlocking. Redis implements distributed locks, I believe everyone is already familiar with it, so I won't be long-winded here.

The third step is to use annotations in the business code.

@EnableRedisLock(lockKey = "student", expireTime = 10, timeUnit = TimeUnit.SECONDS, retryTimes = 5) 
public void method1(Student student) { 
    // write business logic here 
}

Just add a comment directly on the method that needs to be locked. How easy is it? Use it in your project quickly.

Okay, so I'll introduce the content of a comment by myself. Have you learned it?

- END -

After reading three things ❤️

If you think this content is quite helpful to you, I would like to invite you to do three small favors for me:

  1. Likes, reposts, and your "likes and comments" are the motivation for my creation.

  2. Follow the public account "Java Fighting Emperor" and share original knowledge from time to time.

  3. At the same time, reply "666" in the public account to receive 1,000 Internet interview questions for free

Guess you like

Origin blog.csdn.net/Java0258/article/details/109242683