What are annotations?

Java annotations were added to Java5 to provide metadata to Java code. As metadata, annotations do not directly affect your code execution, but there are some types of annotations that can be used for this purpose.

Annotations are a type of metadata that can be thought of as a special kind of comment that provides a formal way to add information to your code and is used to help you write code faster.

In short, annotations have four main functions:

  • Generate documentation: Generate metadata into Javadoc documentation;
  • Compile-checking: The compiler checks code at compile time. For example, the @Override annotation prompts the compiler to see if it overrides a parent class’s method.
  • Compilation dynamic processing: mainly used as dynamic generation code, such as some help classes, methods, through annotations to achieve automatic generation;
  • Running dynamic processing: A typical example is using reflection to inject instances;

Java provides three types of annotations: built-in standard annotations (see below), meta-annotations (annotations that modify annotations, which are the most benchmark annotations), and custom annotations (users can customize annotations, such as @Retention, @target, @Inherited, @Documented, and @REPEATable).

In actual project development, annotations are usually from Java native annotations, meta-annotations, Spring and other frameworks (such as @Resource, @Bean, lombok’s @data, @slf4J, etc.).

Common annotations

Some common Java and Spring annotations are as follows:

  1. Deprecated – the tagged content is no longer recommended for use;
  2. @override – Can only annotate methods, indicating that the method overrides a method in its parent class;
  3. @SuppressWarnings – Warnings generated by the annotated content that the compiler will keep silent on;
  4. @interface – Used to define an annotation;
  5. Documented — Include the Documented content in javadoc;
  6. Inherited – Can only be used to annotate “Annotation type”. Annotations annotated by Inherited are Inherited and agree with the Inherited form of the class.
  7. @Retention — can only be used to annotate the “Annotation type”, and it is used to specify the Annotation’s RetentionPolicy property, which indicates whether the Annotation’s existence phase is reserved for source (compile time), bytecode (classload), or runtime (run in the JVM), For an idea of the annotation declaration cycle, see the following figure:

In general, if Retention is set to source and class, then it needs to be inherited and implemented, because when loaded into the JVM, the annotations for both are erased and therefore ineffective. (Lombok’s @data annotation adds the get/set method to this process.)

  1. @target — can only be used to annotate the “Annotation type,” and it is used to specify the Annotation’s ElementType property, which represents the scope of the Annotation by enumerating the class class, For example, on TYPE (interface, class, enumeration, annotation), FIELD (FIELD, enumeration constant), METHOD (METHOD, PARAMETER), annotation (annotation), CONSTRUCTOR (CONSTRUCTOR), LOCAL_VARIABLE (local variable) (PACKAGE, PACKAGE, etc.
  2. Repeatable- indicates that the annotation modified by this annotation can be applied to an object multiple times, but each annotation can have a different meaning.

Here are some important Spring notes:

  1. @Configuration

Annotations on a class are used to configure the Spring container (context) as part of the Spring XML configuration file.

  1. @Bean

Annotations on methods (methods that return an instance), equivalent to spring’s XML configuration file, register bean objects. The @bean annotation defaults to the singleton scope.

  1. @ComponentScan

Annotation on class, used to scan Component;

  1. @WishlyConfiguration

Combined annotations can replace annotations 2-3.

Above, 1-4, are the relevant annotations for configuration classes;

  1. @Component

Typically on a class, indicating that it is a component and telling Spring that the class creates beans;

  1. @Repository

Indicates that the object is used by the Data Access layer (DAO);

  1. @Service

Indicates that the object is used by the business logic layer (SERVICE).

  1. @Controller

This is the controller’s declaration that the object is used in the presentation layer;

The above 5-8 are all annotations on declared beans;

  1. @resource: Automatic dependency injection

  2. Autowired: Automatic dependency injection;

Note: Both are used for dependency injection, but Resource is injected by Name by default, while Autowired is injected by Type.

  1. Inject: Manual dependency injection;

Here’s how Spring starts the process between containers and components:

  • When you start Spring, you start the container first;
  • By default, when the Spring container is started, it looks for loadable beans in the container scan scope, and then looks for beans on which properties and methods have @Resource annotations;
  • Check whether the name attribute in the @resource annotation parentheses is empty. If it is empty, check whether the bean ID in the Spring container is the same as the variable attribute name of the @resource annotation. If yes, the match succeeds. If not, check whether the bean ID in the Spring container corresponds to the same type as the attribute of the variable to be annotated by @resource. If so, the match succeeds; if not, the match fails.
  • If the name attribute in the @resource annotation bracket is not empty, check whether the value of the name attribute is equal to the id name of the bean in the container. If so, the match is successful. If not, the match fails.

Some other notes:

  1. @profile

The @Profile annotation can be used by any class annotated with @Component or @Configuration. When DI is used for dependency injection, it is possible to inject beans corresponding to the current running environment, depending on the environment indicated by @profile.

  1. @data: On a class, provide the get, set, equals, hashCode, canEqual, toString methods

  2. AllArgsConstructor: Note on a class that provides the class’s full parameter construction

  3. NoArgsConstructor: Note on a class that provides a no-argument construction of the class

  4. @setter: on properties, provide set methods;

  5. Getter: Annotates a property and provides the get method

  6. EqualsAndHashCode: On the class, provide the corresponding equals and hashCode methods;

  7. @log4j / @slf4j: Note on the class, provide the corresponding Logger object, variable named log

  8. @after: indicates that the method is executed After other methods;

  9. @before: indicates that the method is executed Before other methods;

  10. @around: indicates that the method is executed before and after other methods;

Custom annotations?

Common annotations mentioned above can reduce code volume and make code structure more concise and clear, but they are not enough. Custom annotations are sometimes needed for business scenarios or to keep code structure clean.

In general, for example, to set up the log system, or monitoring alarm system, you need to upload or provide some QPS, RT, etc., if the code to write directly in the project code, so will be contaminated project code, and, in the project will be a lot of these duplicated code, the custom annotation is useful!

How to solve? That’s the idea of using APO aspect programming and reflection! This problem can be solved elegantly by writing aOP-related configuration information into annotations.

Reflection is to get information about the Java runtime, and AOP aspect programming is to be able to determine directly in Spring’s AOP whether a method has custom annotations — if so, the custom annotations will load the related monitoring logic on the related methods.

For this example, take a closer look at the code at the end of this blog post.

The resources

Common annotations

Java custom annotations

Notes written by Java3y, great