In this article, we’ll take a look at some of the Spring annotations, as shown in the following figure. Some of the annotations are listed in several ways:


If the graph is not clear, run the following code to print all the results.

Spring’s current trend is to use annotations in conjunction with Java code to define behaviors, properties, functions, rules, and extension points rather than configuration, so combing through annotations is also a good way to comb through Spring’s feature points. A thorough comb can fill in the gaps in our knowledge.

Find all annotations

First, let’s create a project, use SPRING INITIALIZR to generate a project template that introduces various SPRING components, and then introduce the following toolkits:

< the dependency > < groupId > org. Reflections < / groupId > < artifactId > reflections < / artifactId > < version > 0.9.11 < / version > </dependency>Copy the code

With the reflection kit, we can create a Spring Boot application that prints out all the Spring framework annotations in one line:

import org.reflections.Reflections;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
@Component
public class ScanAnnotationRunner implements CommandLineRunner {    @Override 
 public void run(String... args) 
                throws Exception {        
    new Reflections("org.springframework") .getSubTypesOf(Annotation.class) .stream() .map(clazz->clazz.getName()) .sorted() .forEach(System.out::println); }}Copy the code

The output is not shown here, but let’s go through some of the important notes one by one.

The annotation

Java’s annotations (similar to C#’s Attribute feature) are, in plain English, the ability to label code. We can configure the retention phase of this tag, source code only, source code + bytecode, source code + bytecode + runtime. By introducing annotations, we can quickly and easily bring code to life, greatly improving code readability and extensibility. Annotations themselves do not have any power, just a tag, but we can define various tags and then implement various tag handlers to extend, enable, attribute definition, behavior definition, rule definition, association processing, metadata definition and so on for classes, methods, attributes and even parameters. When implementing various frameworks, we often use custom tags to make it easier for framework users to enable (or customize) some of the framework’s capabilities and apply them to our applications simply by introducing the right annotations in the right place.

It’s not just the authors of the framework who make extensive use of annotations. In previous articles in this series, we’ve customized annotations a number of times, including by defining @metrics annotations in conjunction with Spring AOP to enable application startup Metrics, logging, exceptions, and so on. We have data signing by defining the @sign annotation in conjunction with Spring MVC’s ResponseBodyAdvice, We also often define all kinds of custom annotation with Spring MVC HandlerMethodArgumentResolver permission check and so on function. With this pattern, our core business logic can be kept clean, with annotations and AOP giving our code additional power.

You might say that annotations are still intrusive, that we need to couple the annotations defined by the framework, that there is no solution to the problem, that 100% non-intrusive means a loss of readability, and that the functionality and capabilities of the code should be clustered together, which is why Spring doesn’t recommend XML for configuration right now. The Java core class library doesn’t have annotations, but Spring has plenty of annotations, and Spring has become the standard for Java development. So most of the time if we want our framework (RPC etc.) to be completely non-intrusive, we can use Spring’s annotations @autowired, @Controller, @Service, etc., with various package specifications. In fact, we can identify the function of the target element almost completely. It is entirely possible to implement 0 intrusion enhancement.

Without going into details on how to implement custom annotations, let’s briefly review a few meta-annotations (annotations of annotations) :

A. @Documented: An annotation will be listed in the Javadoc document for the element annotated with this annotation. It is generally good to have this annotation

B. @target: The Target elements to which annotations can be applied, such as classes, methods, attributes, parameters, and so on, need to be thought through

C. @Retention: Retained source code only, reserved to compiled bytecodes, or loaded at RUNTIME. More than 90% of applications parse annotations at RUNTIME for additional processing, so in most cases we set the configuration to retentionPolicy.runtime

D. @ Inherited: Spring’s @Service does not have an inheritance feature, but @Transactional does have an inheritance feature. Be aware of this when using Spring annotations in OO inheritance systems. Taking annotations for granted that they can be inherited by subclasses can cause unnecessary bugs and requires careful consideration of whether to enable inheritance

E. @ the Repeatable: Java 8 introduced characteristics, by defining repeatable annotations associated annotations container, little syntactic sugar improves the code readability, the element has multiple repeat annotation is actually very common things, such as A method can be A role can access B role can access, and A method to timing task execution, also need to be executed in A condition in B conditions is carried out

F. @native: Whether to generate marked fields in.h header files. This meta-annotation is rarely used unless Native programs need to interact with Java programs

Now let’s go over some of Spring’s commonly used noteworthy annotations in a few ways.

Spring Core Notes

A. Let’s start with the stereotypes: It defines the various components managed by Spring by category. @Controller defines the presentation layer components, @Service defines the business logic layer components, @Repository defines the data access layer Repository components, @Component defines other components (such as components that access external services), As mentioned earlier, while these annotations make no difference, a proper classification of components is significant, not only for readability but also for more automatic enhancement of different types of components using AOP

B. Let’s look at some more IOC notes: @autowired, no need to say more; The @required annotation is used in setter methods to mark property values that need to be assembled by Spring. This annotation is deprecated in current versions of Spring, and constructor injection is now recommended. The @qualifier is used to inject beans by defining qualifiers for beans, using the @AutoWired equivalent of @Resource, and of course, a common use is to embed other annotations to distinguish beans and use them in conjunction with @AutoWired. See the @loadBalanced annotation for Spring Cloud later; @Value is used to inject property configurations or SpEL expressions (the former is a common usage, the latter is a bit more powerful to get values from other objects); @lookup can implement method injection through this annotation if our class is singleton and we want Spring to inject dependent objects from the Prototype lifecycle (one new at a time)

C. Then let’s look at some notes about the transaction: @ EnableTransactionManagement for open transaction management, using the Spring Boot if the introduction of the Spring Data do not need to manually open (but recommended when using transactions or through the log to verify whether the transaction management effect); Transactional @Transactional is known for starting transactions and setting propagation, isolation, rollback conditions, etc. @ TransactionalEventListener callback method is used to configure affairs, may submit, after before the transaction is committed, and roll back after the completion of several stages to accept callback event.

The D.@order annotation sets the load Order of spring-managed objects. As we saw in previous articles on AOP, we sometimes have to set @Order to Order cuts in Order to avoid problems. In some business scenarios, We tend to define a set of @ components like filters and get a set of beans from the container, where the order in which business components are run is important and can be sorted in this way

The @aliasfor annotation can alias a set of annotation attributes to each other, which will make code clearer if there is ambiguity, and is also used to create composite annotations. Spring MVC’s @getMapping annotation is a composite annotation created based on @requestMapping. We can easily implement annotation inheritance in this way

Spring Context annotations

A. Let’s start with some Configuration annotations: @Configuration is used to annotate Configuration classes, enabling Java Configuration Bean Configuration; @bean is used to configure a Bean; @ComponentScan (@ComponentScan is used to configure a group of @ComponentScan, Java 8 can directly configure multiple @ComponentScan using the repeat annotation feature) for scanning the package configuration Bean; @propertysource and @propertysources are used to import configuration files; @Conditional is used to set the associated condition class and enable Bean configuration when appropriate (Spring Boot automatic configuration foundation); @import is used to Import other configuration classes; @importResource is used to import XML configurations that are not Java configurations. @profile is used to specify enabling configuration under the appropriate Profile; Lazy is used to tell the container to delay instantiating the Bean until it is used (by default, the Bean is instantiated when the container starts to check for any problems); @description is used to set a Description for the Bean; @scope is used to set the life cycle of the Bean; @primary is used to specify the preferred Bean when multiple beans are defined

B. Other annotations include @EventListener to set the callback method to listen for various spring-specified and custom events; @enableAspectJAutoProxy is used to enable @aspectJ-enabled Aspect configuration support, which does not need to be explicitly enabled when using Spring Boot to introduce AOP initiators

Spring Web annotations

Spring MVC annotations correspond to various aspects of Spring MVC functionality. Let’s take a look:

A. Start with three composite annotations that define the Bean’s particular life cycle: @requestScope, @SessionScope, and @ApplicationScope. These three quick composite annotations can be used directly in Web applications where beans are created to follow the request, session, and declaration cycles of the application

B. The @xxxMapping annotations are used to configure the HandlerMethod to match different Http methods. It is also possible to use @requestMapping and manually set the Method

C. @responseStatus can be used in both method and exception. The former will directly make the request get the specified response code or reason (can be used with @ExceptionHandler), and the latter can achieve the specified response code or reason when the specified exception is encountered. @responseBody We use it most often when we implement Restful interfaces (@restController) to output the returned content (serialized) to the request body

D. Spring MVC gives us various annotations to get parameters from various parts of the HTTP request, @requestbody from the RequestBody (handling complex data such as JSON), @requestheader from the RequestHeader, @cookievalue from the cookie, @sessionAttribute from the session, @requestAttribute from the attributes of the request (such as some temporary data that filters and interceptors manually set), @RequestParam from the request parameters (handling simple data, key-value pairs), @pathVariable from path fragment, @matrixAttribute matrix variable allows us to use special rules to append parameters to URL paths (semicolons to distinguish different parameters, commas to add multiple values to parameters)

E. @ControllerAdvice is an important annotation that allows us to configure controller enhancements (@requestMapping) in a central place (@RestControllerAdvice is similar, It’s just adding @responseBody to @ExceptionHandler. So what enhancements can be applied? The first is to use @ExceptionHandler for unified global exception handling; InitBinder is used to set WebDataBinder, which is used to automatically bind foreground request parameters to the Model. The third is @modelAttribute, which allows @requestMapping globally to get the key-value pairs set here. Of course, @initBinder and @ExceptionHandler are not defined within @ControllerAdvice (as global enabler), but are also defined within Controller to apply to a Controller

F. Other annotations such as @crossorigin can be used on Controller or Method (with @RequestMapping needed) to set up fine-grained cross-domain behavior

In the previous article we also mentioned, for the Spring MVC, define your own annotations to the parameters, the method, the controller, cooperate HandlerMethodArgumentResolver, XXAdvise and Mrs Interceptor to achieve specific functions to use common, For almost all non-business crosscutting concerns, we should not repeat a single line of code in a method implementation.

Spring Boot annotations

A. look at some of the contextual annotations: @ ConfigurationProperties common (with @ EnableConfigurationProperties annotations to set up the need to enable the configuration of the class), used to customize the configuration class and associated configuration files; @ DeprecatedConfigurationProperty for marking abandoned configuration and set alternate configuration and inform abandoned causes; @ ConfigurationPropertiesBinding is used to specify a custom converter is used to configure parsing the type conversion; @ NestedConfigurationProperty used to correlate the type of external configuration as a nested class

Automatic configuration is one of the most important features of Spring Boot. In previous articles, I made the point that IOC is a good thing, but it doesn’t make sense to leave some of the default configuration and assembly of components and components to external users. Components should be able to automatically self-configure to achieve emergency use, only when the need to customize components to require external personalized configuration: The @enableAutoConfiguration annotation enables automatic configuration. For SpringBoot applications, we use the @SpringBootApplication composite annotation directly. @AutoConfigureOrder (the lower the value, the higher the priority), @AutoConfigureAfter, and @AutoConfigureBefore are used to set the automatic configuration class loading order and accurately control the loading dependencies. Sometimes our automatic configurations are interdependent or interfere with each other and need to be manually adjusted

C. Finally, let’s take a look at the dozen or so configuration conditions that are key to complete automatic configuration: @conditionalonBean matches conditions only if the container already contains the specified Bean type or name; ConditionalOnClass matches only if the specified class exists on the classpath. @ ConditionalOnCloudPlatform only when the specified cloud platform is active condition matching; ConditionalOnExpression Configuration annotations for conditional elements that depend on the value of the SpEL expression; ConditionalOnJava conditional match based on the JVM version of the application running; ConditionalOnJndi conditional matches based on JNDI availability and can look up the specified location; ConditionalOnMissingBean Matches only if the container does not contain the specified Bean type or name; @ ConditionalOnMissingClass only when the class conditions specified does not exist on the classpath matching; @ ConditionalOnNotWebApplication only if not WebApplicationContext (not the Web project) matching conditions, the corresponding @ ConditionalOnWebApplication; ConditionalOnProperty checks whether the specified attribute has the specified value. ConditionalOnResource specifies that the condition matches only if the specified resource exists on the classpath. @ ConditionalOnSingleCandidate when a container contains only the specified Bean class and can be judged when only a single candidate matching conditions. In fact, all of these implementations extend the SpringBootCondition abstract class (implementing the Condition interface mentioned earlier), and we can implement our own Conditional annotations (with the @Conditional annotations associated with our own implementation of SpringBootCondition).

Spring Cloud annotations

As we mentioned in the first article in this series, Spring Cloud uses various EnableXXX annotations neatly to enable a function. I won’t explain these annotations here. Using the Spring Boot component is very simple. Basically, POM+EnableXXX+ set configuration file trilogy.

A. First of all, there are some comments in the Netflix package, not to mention the various EnableXXX. Refer to the previous article, @RibbonClient was not introduced before. Can you further configure or customize where to get the server list, load balancing policy, Ping (service authentication policy), and so on

The @SpringCloudApplication in the b. client package is not used in the previous article. So this is a compound annotation which is @SpringBootApplication+ @EnableDiscoveryClient+ @Enablecircuitbreaker, Spring Cloud there’s a lot of stuff there, Or their own definition of a functional annotations to the steadfast; The @loadBalanced annotation is used in conjunction with RestTemplate to form a load-balancing Http client. The implementation principle is actually an @qualifier annotation. Spring will for all RestTemplate @ LoadBalanced to join a LoadBalancerInterceptor (implementation ClientHttpRequestInterceptor) to achieve load balancing

C. The annotations below the sleuth package are related to link tracing. The most common annotation is to manually set the span name by using @spanname. Other annotations are not commonly used for business development

conclusion

Well, after writing this article I found that I saw @markdown’s ** giddy, please like support. In this article we printed most of the spring-related annotations in code, which is a good way to familiarize yourself with other frameworks’ annotations (after all, annotations are an important entry point into the handy features that frameworks give us, and a good understanding of annotations is often a good understanding of the rich features that frameworks give us). We then combed through the various Spring annotations, focusing on the following areas:

  1. Meta-annotations, that is, annotations of annotations

  2. Some annotations related to the Spring container, including @Qualifier, @Aliasfor, @Order, and other seemingly unimportant but important annotations

  3. Spring Java configuration related annotations, including conditional annotations

  4. Some notes related to Spring Boot automatic configuration

  5. Many annotations can be applied to types, methods, and parameters at the same time, and sometimes have slightly different effects in different places

We know that annotations are just a sign, and the implementation principles behind how annotations work are quite varied. You can explore the implementation principles behind the various Spring annotations described in this article.