I’ve asked a few people around me about Java annotations, and a lot of them say:

Know how to use it, not familiar

I wonder if you are? When I don’t have a systemic study side note, I also is such, after I take the time to study notes, I think, for the notes, the most important is to understand, a lot of people also have seen a lot of comments on the article, but before long will forget, forget about, this is not a problem, can only say that is normal phenomenon.

But for a knowledge point, the more thoroughly you understand, the less likely it is to forget, so today I am going to talk about Java annotations in an easy to understand and try to let everyone have their own understanding, try to remember this important knowledge point!

What are annotations?

The first step in learning about annotations is to start with the basics, what are annotations?

Annotations and reflection are very important things that are overlooked in Java, and in mainstream Spring they are full of annotations. Annotations and comments are very similar, but they are very similar in nature. Annotations are for us programmers, and annotations are for programs.

I hope you will pay attention to the following two points:

1. Comments are similar to comments. 2. Comments are for us programmers, and annotations are for programs

For a preliminary understanding of annotations, we start with the above two points. Let’s look at annotations first, for example:

 

So that’s a comment, so what’s a comment for? This is simply a description of the relevant class or method, such as the Test class here. The comments above give us a general idea of who wrote the class, what it did, and when, but there could be more information.

So, you have to understand what annotations are for, they’re for us programmers, and when we see them, we know, oh, this is what this class looks like…

Comments are for programmers. What about annotations? The difference is one word, the annotation is for the program to see, just remember.

Further understanding of annotations

So as we said, comments are very similar to comments, comments are for us, comments are for programs, so it’s easy to understand, this is for programs, and you might be a little confused, but LET me explain a little bit more.

First, get a sense of what an annotation is, like this one we wrote in our code:

/** * @description user * @author ithuangqing * @date 2020-07-31 15:33 **/ @repository public class UserBean {private String name; private int age; } 12345678910Copy the code

So @repository here is an annotation, and if you look at this code, there’s a comment on it, and if you look at the comment, it makes sense, but if you look at @repository, it doesn’t make sense. What is it? What is it for?

So we look up, we kind of know, oh, this is an annotation, and with this annotation, the UserBean is going to be loaded into the Spring container, and we can get this information, but what does it actually do, how does it work, how does it hand the UserBean off to Spring to handle, this internal implementation, We don’t know.

But, although we don’t know, there is one thing it does know. What is it? A specific application, that is, a specific application, when it sees a UserBean with an @repository on it, knows that it needs to load the UserBean into the Spring container, The programmer then performs a series of operations to load the UserBean into the Spring container.

So, you should know by now:

Comments are for people, comments are for programs.

Let’s take a closer look at what annotations are:

In the program, can put the annotations as a special kind of tag, is commonly used to mark class, or interface, etc., these tags have some characteristics, such as, at compile time (javac command to compile Java source files into a bytecode file class), class loading and running time (using the Java command byte code file, Class life cycle begins, from load to unload) is read (usually there is a special program to read the annotations, use reflection technology to parse the annotations, and then do something with the information)

Yes, here’s what you need to know about annotations:

For annotations, there is a program that reads it, parses it, and then acts on the resulting message.

So how the program knows what to do when it reads an annotation depends on the definition of the annotation itself. For example, the @repository annotation is defined to load the annotated object into a Spring container. Then the specific program that gets this annotation knows what to do.

At this point, you should know what annotations are, of course, some conceptual things, and you should have some insight into how annotations work…

A simple classification of annotations

This is a fun idea that doesn’t require you to lose a lot of brain cells.

Annotations are classified, and there are generally three types of annotations:

  1. Custom annotations (actually very few)
  2. JDK built-in annotations (@override validation method Override)
  3. Annotations in frames

There are several different types of annotations. First, we can write our own annotations (which will be explained below), and the JDK itself has its own annotations. Let’s take a look at the code and you’ll see:

 

Override: toString (); Override: toString (); Override: toString (); Override: toString (); Override: toString ();

 

This is about the JDK’s built-in annotations, and the last one about the framework, which I think you’ll know if you’ve ever studied Spring, is @Controller, which is pretty familiar.

The nature of annotations

Now that we have a general idea of what a annotation is and some of its categories, we have a conceptual idea of what a annotation is, but what is the nature of the annotation?

An annotation is essentially an interface, so let’s see how to define an annotation.

public @interface Main {
}12
Copy the code

This is the same as an interface, except that it has an @, or an interface, so we can use XJad to decomcompile this annotation.

 

See, Main is just the interface definition, and then it inherits the Annotation, which is enough to show that annotations are actually interfaces.

This temporarily talk about this, remember can!

How to define annotations

Now let’s talk about how to customize an annotation. As mentioned above, an annotation is essentially an interface, and the definition of an annotation is briefly illustrated below:

public @interface Main {
}12
Copy the code

Think about how we normally define an interface, do we use the keyword interface, and what about classes? The class keyword is usually declared by a keyword. Obviously, the key for defining annotations is @interface, which has an extra @ sign with the interface definition, but the definition of annotations is more than that.

Yuan notes

We’re going to introduce the concept of a meta-annotation, so let’s think about it for a second. Annotations, as we said above, can be used to tag classes, interfaces, methods, etc. So there’s a problem here. Let’s say I define a Main annotation like this:

public @interface Main {
}12
Copy the code

So, can I use this annotation on a class as well as on an interface or method? General classes, interfaces, methods, etc., are somewhat different, so it is best to distinguish between them. That is, some annotations can only mark classes, some annotations can only mark methods, etc., so you need to limit the scope of annotations.

So what do we do with this? The answer is a meta-annotation. So what is a meta-annotation?

Meta-annotations are annotations that mark annotations

For example, if we define the Main annotation and specify that it can only be used to mark methods, we can do this:

 

We’ve added an annotation @target, followed by an argument (as we’ll see below). This parameter ElementType.METHOD means we’re using this annotation to annotate methods.

 

See, it works with our main method, but can’t it work with a class? Let’s try:

 

So this @target is a meta-annotation that can be used to annotate annotations, that is, to mark annotations.

There are generally the following main points about meta-annotations:

  1. Documented
  2. @target specifies where the annotation should be used. If not, any position can be used
  3. @Retention (Annotated Retention strategy)

And just to mention the last one here which is the Retention policy for statement annotations, @Retention, what does that mean?

The retention strategy is to describe the three major phases of code from writing to compiling to executing.

 

I’ve drawn this pretty clearly. Generally, our annotations are reserved for runtime, so it looks like this:

 

Of course, it depends on the situation.

Now you might notice that this annotation can have parameters in it, right? Of course it can. Here’s a quick demonstration of the syntax of annotations, as you’ll see below:

 

Then take a look at the use:

 

It’s actually pretty simple!

Basic usage syntax for annotations

Let’s take a look at the syntax of annotations and how they are used.

For annotations, we know how to define them, such as simply defining a annotation:

 

That’s easy, but let’s move on. We can also define attributes for annotations:

 

Although this property looks like a method, it is a property, and annotations are special, so now we use this annotation:

 

This time it complains, tell we need a value value, but it is better to understand, your annotations defined defined a value attribute, so you need when using the attribute values to use, then you said I can not, you can, when the custom annotation attributes you need to add a default value, is like this:

 

It can be set to an empty string or a specific value. We can also set multiple property values, like this:

 

If you only assign a value to an attribute, you can use it like this:

 

So some of you might be wondering, is this hello for value or name? By default, it’s always value, so keep that in mind.

When assigning multiple attributes, you must specify the name of the attribute, like this:

 

PS: One of the strange things about annotations is that for annotations, we can define attributes, but the attributes of annotations really look like methods. But in annotations, they are attributes and can be assigned directly.

Type of property

The attributes of an annotation were briefly described above. What types of values can these attributes take? There are roughly as follows:

  1. Basic data types
  2. String
  3. The enumeration
  4. Class
  5. Annotation type
  6. Arrays (one-dimensional arrays of the above types)

Let’s look at an example of arrays, like this:

 

The same goes for using:

 

How do you really understand annotations

The reason we usually ignore annotations is that there are a lot of things we just need to use, like this:

 

As for how annotations are defined and how annotations work, I don’t know much about them. It seems that we need to customize annotations very little, so if we don’t systematically learn annotations, we will ignore many things of annotations and only use them, that is, @xxx

So, starting today, I want you to remember that for annotations, there must be three processes:

  1. Custom annotation
  2. Using annotations
  3. Read and execute the process

The first step is to define the annotation. This annotation can be used in IDEA by holding Ctrl and clicking @repository.

 

] (www.ithuangqing.vip/wp-content/)…

This is the definition of the @repository annotation. Then let’s look at the use of @repository:

 

Then it’s time to read the annotation. How? Many people are vague about this, and this is the biggest obstacle to understanding annotations.

We usually is the use of annotations, definition of annotation and read the general framework of what is done to us, we don’t look at the source code in general don’t know what’s going on, it is not clear how the annotation works, simple to understand is to read comments need to rely on reflection, then do the corresponding processing.

But I’m sure you’re as curious as I am as to why the @repository annotation is then loaded into the Sring container to generate a bean.

Remember what I’ve been saying since the beginning? Annotations need to be read by a special program, and then read the information from the annotations to perform the corresponding operation.

So here, in Spring’s source code, there must be some program or programs that do this.

Annotation reading (how annotations work)

This is the definition of annotations and how to use them, but I’m going to separate out the reading of annotations, because that’s the point of annotations. One of the reasons people don’t understand annotations is that they don’t know what they’re doing after they add them.

How do annotations work? Understanding this will help you greatly in understanding annotations.

Annotations are primarily read by reflection

For reflection, it can only read bytecode information in memory, and then remember the annotation scope @target?

It has several main scopes, namely this image, to review:

 

In the case of retentionPolicy. CLASS, this refers to the bytecode stage, where the bytecode file is generated from Java source files compiled by JavAC and the CLASS bytecode file is actually on disk, not in memory.

Reflection can only read bytecode information from memory, so the annotation’s retention policy is that the @Target can only be RUNTIME, which can still be read at RUNTIME.

My Understanding (essence)

A lot of people annotate don’t understand, or feel very vague one reason is that you let me define an annotation, I can also according to the basic annotation syntax to define an annotation, you say how to use annotations and I know that in the class, methods using @ + name of the annotation on the way, but also to give priority to, further understand a bit fuzzy, such as:

  1. Why do you use it that way?
  2. How does it work? How does it work?

Do you think we could just put an @+ annotation name on a class or method? How does the follow-up work? There are three steps to annotating:

  1. Custom annotation
  2. Using annotations
  3. Read annotations (this is what most people lack and is the key to why most people don’t understand annotations)

To understand what is under the annotations, and comments there, there must be some similarities, both of which is to provide additional information, like notes, annotations are programmers see to us, see the comments we know what a class is, have a purpose, see method annotation, we know what effect this method need any parameters as well as the meaning and so on, then w annotations, Annotations are actually for the program to see. When the program reads the annotation, it gets some information from the annotation about what to do with the class or method marked by the annotation, etc.

To understand the above, let’s use an example from Spring to illustrate.

We need to register our bean in the Spring container. This usually has XML configuration mode and annotation mode. Of course, we are talking about annotation mode here. That is, using @+ annotation names, as a simple example:

 

This is a familiar annotation that registers our Person class with the Spring container. Here’s how to use this annotation:

 

This definition is already familiar. @Component is also an annotation, which is basically an annotation that registers a class in the Spring container. And the later ones like @Repositoy we’re talking about now and @Service and @Controller are all based on @Component.

One of the things that needs to be clear about any of these annotations is that the class you want to use these annotations on automatically registers with the Spring container, which is much easier than writing XML configuration. So we just put @repositoy on a class, and it’s registered to the Spring container, okay?

The definition of the annotation is very simple. There is nothing there. How can it be automatically registered in the Spring container?

Remember the three steps of annotation? First you need to define an annotation, then is the use of annotations, the annotations is how work procedures will be necessary to read annotations, the annotations is just like a symbol, a label, the @ Repositoy here, for example, when a class is the annotation marks, and so when the program to read the note, this program will know, oh, We need to register this class in the Spring container. How do we know to register this class in the Spring container? That’s what @Repositoy told it. In addition, we know that annotations can usually set a value property value, which can be retrieved by reflection technology or something like that, so this value may be used in the process of registering the class in the Spring container, such as setting the name of the bean.

We typically use annotations, and we need to configure package scanning for annotations in the Spring configuration file:

<context:component-scan base-package="com.ithuangqing.*"/>
1
Copy the code

This is basically a scan to see which class Repositoy is using the @repositoy annotations, and then you need to do something special to register them to the Spring container. Spring will parse this tag.

registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
1
Copy the code

Then is in ComponentScanBeanDefinitionParser processing, specific processing code is as follows:

@Override public BeanDefinition parse(Element element, ParserContext parserContext) { String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); // Actually scan for bean definitions and register them. ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); // Set<BeanDefinitionHolder> beanDefinitions = scanner.doscan (basePackages); / / scan file, and translated into spring bean, and register registerComponents (parserContext. GetReaderContext (), beanDefinitions, element). // Register other related components return null; } 1234567891011121314Copy the code

The main purpose of the above code is to scan the file under the Base-package, convert it to the bean structure in Spring, and then register it with the container…

How’s it going? Is it getting harder to read code? This is normal, just remember that annotations are read by a specific program and then processed, and this processing logic is often complicated, especially in frameworks.

Gets the attributes of the annotation

While it’s important to understand how annotations work, let’s talk about the final step in annotation usage: a specific program to read annotations.

Annotation use ultimately depends on the program to read the annotation, get some information about the annotation, and then decide what to do next, so we need to know how to get the attribute value of the annotation.

In fact, the attributes of annotations, the technology used is reflection, reflection is a very important knowledge point, later will write a separate article to talk about easy to understand.

Let’s look at how to use reflection to get the attributes of an annotation. , mainly the following three basic methods:

Public Boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return GenericDeclaration.super.isAnnotationPresent(annotationClass); } public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {return (A) annotationData().annotations.get(annotationClass); Public Annotation[] getAnnotations() {return AnnotationParser.toArray(annotationData().annotations); } 1234567891011121314151617Copy the code

Then look at a simple piece of code that demonstrates using annotations to get annotation properties

public class Test { public static void main(String[] args) throws Exception { Class<Test> testClass = Test.class; Method toGetString = testClass.getMethod("toGetString"); / / get annotation object Main Main = toGetString. GetAnnotation (Main. Class); System.out.println(main.value()); } @main (" this is the value of a custom annotation ") public static String toGetString() {return ""; }} 123456789101112131415Copy the code

It’s really easy. Remember the above three ways to get annotations, and we’ll talk more about reflection later.

By now we know that annotations need to be defined and then used, so how this works is probably a program that uses reflection technology to read the annotations, get the information inside the annotations and then do something about it.

conclusion

That’s about it. Maybe you read it and forget it, maybe you didn’t read it at all, but I want to keep it in mind:

  1. Custom annotation
  2. Using annotations
  3. Read the note