First of all, conclusion: Annotation is a means by using a method similar to @xxx on classes, methods, or attributes, etc., and then the content of the tag can be parsed and processed accordingly through the reflection mechanism.
Annotations are an important knowledge point in Java. It has been introduced after Java5, especially in the spring framework. Commonly used include @controller, @service, etc. This article will analyze it based on the implementation principle of the annotation and implement some demo codes.
1. Annotation definition method
Just go to the code and look at the definition of the @Service annotation in spring:
@Target({}) @Retention() @Documented @Component public @interface Service { String value() default ""; }
You can see that the definition of annotation is very similar to the interface definition, but with more @ characters, there are the following conventions in the definition of annotation:
- Only attribute names can be defined, no methods can be defined
- The visibility of attributes is only public and default, if not written, the latter will be defaulted.
- The types of attributes can only support: basic data type, string, class, enum, Annotation type and above arrays
- You can add the default keyword to specify the default value. When a field does not specify the default value, you must specify the value of this field when annotating.
- When using value as the attribute name, you can not specify value="xxx" explicitly. If you can use @Service("xxxService")
2. Meta-annotation
The so-called meta-annotation is annotation specifically annotated by the default implementation in Java. The total number of meta annotations is 5. The @Service annotations we mentioned above are examples to break each one:
1.@Target
This annotation is used to represent the scope of use of the current annotation. @Target({}) means that the @Service annotation is specially used to annotate to classes, interfaces, or enumeration types. When adding this annotation to the method, an error will be reported. You can see that the annotation position is an enum type, and the complete definition is as follows
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
2.@Retention
This annotation is used to represent the life cycle of the current annotation. Speak humans is when this annotation will be retained. For example, @Retention() means that it is still valid during the program operation. At this time, the annotation information can be obtained through reflection. The complete enumeration definition is as follows
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see */ RUNTIME }
3.@Documented
When annotated by this annotation, the use of the javadoc tool to generate the document will have annotation information.
4.@Inherited
This annotation is related to inheritance. When annotation A is added, and annotation A is added to a certain class, the subclass of this class will inherit the A annotation.
@Inherited public @interface A{ } @A public class Parent{} public class Son entends Parant{}//Son class inherits the A annotation of the parent class
5.@Repeatable
As the name suggests, this annotation is the ability to repeat the annotation. Imagine a scenario where we need to execute a task regularly, which needs to be executed every Monday and Wednesday, and this time can be flexibly adjusted. At this time, this meta annotation can come in handy:
@Repeatable() public @interface Schedule { String date(); } public @interface Schedules { Schedule[] value(); } @Schedule(date = "on Monday") @Schedule(date = "Wednesday") public class Executor { }
Note that the content in the brackets after this meta annotation. The specified class is called a container annotation, which means a container that stores these multiple annotations. Therefore, we create a @Schedules annotation as a container annotation for @Schedule. The container annotation must contain an attribute with the name value and the return type is an annotation array that needs to be placed in this container.
3. Customize annotation
Below, we will implement a custom annotation by ourselves using the very common authentication scenarios in web projects as an example.
First, we define the identity of the user of the system, including three identities: super administrator, administrator, and visitor.
public enum IdentityEnums { SUPER_ADMIN, ADMIN, VISIVOR }
Next we define a permission annotation:
@Target({,}) @Documented @Retention() public @interface Authorization { IdentityEnums[] value(); }
Then use the interceptor method to perform unified authentication and management of all pages. Only some key codes are displayed here:
public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { IdentityEnums user = getIdentityFromRequset(request);//Get account information from the request here and judge the identity, and implement it yourself Authorization auth =((HandlerMethod) handler).getMethodAnnotation();//Get the comments above the method if (!(()).contains(user)){ return false; } } return true; } }
Finally, configure the interceptor in the spring configuration file to enable the interceptor:
<!-- Interceptor --> <mvc:interceptors> <mvc:interceptor> <!-- The matching isurlpath, If not configured or/**,Will intercept allController --> <mvc:mapping path="/**" /> <!-- Interceptor类 --> <bean class=""></bean> </mvc:interceptor> </mvc:interceptors>
In actual use, we will add this custom annotation to the method. Only when the identity permissions meet can the page be accessed. The usage method is as follows:
@ResponseBody
@RequestMapping(value = "/management") @Authorization({,IdentityEnums.SUPER_ADMIN}) public String management(HttpServletRequest request, HttpServletResponse response) { ("has permission!"); }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.