Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use annotations

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "how to use annotations". In daily operation, I believe many people have doubts about how to use annotations. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to use annotations"! Next, please follow the editor to study!

Cheng WA's notes on Shouguan

Once annotations are constructed, they enjoy the type checking protection of the compiler. Let's take a look at the next set of code to warm up:

Public class TestService {@ MyAnnotation public void runTset () {System.out.println ("annotation test");}}

Don't wonder, there is not a single annotation in Java called MyAnnotation, but how did this come from? we made it ourselves.

So when the Guanzi is sold out, let's reveal the manufacture of the notes:

@ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface MyAnnotation {}

In this way, a simple note is fresh out. It should be noted that this is not an interface. There is an @ in front of interface. If this logo is left out, it can be very different.

Careful friends may have noticed how there are comments on the definition of annotations.

That's what we're going to talk about, knock on the blackboard and pay attention!

Meta annotations to help

Some meta-annotations are required when defining annotations. There are two above, @ Target and @ Retention.

@ Target is used to define where your annotation will be applied (such as a method or a domain), and @ Retention is used to define at which level the annotation is available, in source code ("SOURCE"), in class files ("CLASS"), or at run time ("RUNTIME"). Java provides four meta-annotations, as follows:

The name is used for "@ Target" to identify where the annotation can be used. ElementType parameters include:

1. CONSTARUCTOR: declaration of the constructor

2. FIELD: domain declaration (including enum instance)

3. LOCAL_VARIABLE: local variable declaration

4. METHOD: method declaration

5. PACKAGE: package declaration

6. TYPE: class, interface (including annotation type) or enum declaration "@ Retention" indicates the level at which the annotation information needs to be saved. The RetentionPolicy parameter includes:

1.SOURCE: comments will be discarded by the compiler

2.CLASS: comments are available in class files, but are discarded by VM

3. RUNTIME:VM will also retain annotations at run time, so you can read the annotated information "@ Documented" through reflection mechanism and include this annotation in JavaDoc "@ Inherited" to allow subclasses to inherit parent annotations.

Annotations are also classified

We created an @ MyAnnotation annotation in the above example. It looks simple and has little content, so this kind of annotation is also called "tag comment", and it can be divided into several categories:

Tag comments: there are no attributes inside the comments. How to use: @ comment name

/ / define @ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface MyAnnotation {}

Single-valued comment: there is only one attribute inside the comment. Usage: "@ comment name (key = value)"

/ / define @ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface SingleValueAnnotation {String name ();} / / use @ SingleValueAnnotation (name = "test") public void singleTest () {}

Multi-valued comments: there was an attribute inside the comment. How to use: @ comment name (key = value, key = value,...)

/ / define @ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface MultiValueAnnotation {String name (); int num ();} / / use @ MultiValueAnnotation (name = "test", num = 1) public void multiTest () {}

The value also has a default

When we are not using tag annotations, if we do not assign values to the attributes in the annotations, the compiler will report an error, indicating that we need to assign values.

This is very inconvenient, sometimes we do not use or the value is fixed and do not want to repeat, then we need to use the "default" keyword to help us solve this problem.

@ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) public @ interface MultiValueAnnotation {String name (); int num () default 0;}

We use the default keyword on the property to declare that the default value of the num property is 0, so that we do not have to manually assign a value to num when using the above annotation.

Notes on the Creator of Ziguan

Annotations have the function of allowing the compiler to compile and check, but if there is no tool to read annotations, annotations will not be more useful than annotations, at least annotations can give developers a more intuitive view of the usefulness of this code.

Back to reflection to create and use "annotation processors", we also need to use reflection mechanisms to construct such tools. Here is a simple example:

Public class AnnotationHandle {public static void track (Class c) {for (Method m: c.getDeclaredMethods ()) {MultiValueAnnotation annotation = m.getAnnotation (MultiValueAnnotation.class); if (annotation! = null) {System.out.println ("name:" + annotation.name () + "\ n num:" + annotation.num () } public static void main (String [] args) {track (TestService.class);}} / * OUTPUT: name:test num:0 * /

In the above example, we used two reflection methods: getDeclaredMethods () and getAnnotation ().

Where getDeclaredMethods () is used to return all the methods of the class, and getAnnotation () is used to get the annotation object of the specified type. If the comment is not present on the method, the value "null" is returned.

Available types of annotation elements

In the @ MultiValueAnnotation annotation above, we define "name" of type String and "num" of type int. In addition, we can use other types as follows:

"basic types" ("int, float, boolean, etc.")

"String"

"Class"

"enum"

"Annotation"

"arrays of the above types"

If a type other than the one above is used, the compiler will report an error. And it should be noted that "basic types of packaging types cannot be used either."

Restrictions on default values

As we have seen in the above example, we can assign values to annotation attributes when using annotations, or we can give annotations a default value when defining annotations, but both show one thing: "annotated elements cannot have uncertain values, either have default values, or provide the value of the element when using annotations."

There is no null value for the base element, so for elements of a non-primitive type, whether declared in use or defined, "you cannot take the null value as its value." Therefore, in actual development, we often define some special values as identifiers that do not exist, such as "negative number" or "empty string".

The strategy of the operation of the three passes

In the previous two hurdles, we learned to define annotations and create annotation handlers. Next we will come to a more in-depth grasp of the notes!

Annotations can also be nested

When we decorate the annotation elements, we see that we can use Annotation to decorate, which is probably a little strange when we see that. I'm here to reveal the secret for you.

Let's take a look at a set of notes:

@ Constraints

@ Target (ElementType.FIELD) @ Retention (RetentionPolicy.RUNTIME) public @ interface Constraints {boolean primaryKey () default false; boolean unique () default false;}

@ SQLString

@ Target (ElementType.FIELD) @ Retention (RetentionPolicy.RUNTIME) public @ interface SQLString {String name () default "; Constraints constraints () default @ Constraints;}

We use the Constraints annotation element in the @ SQLString annotation and set the default value to @ Constraints. At this time, the values in Constraints are the default values defined in the @ Constraints annotation. If we want to use customization, do the following:

@ Target (ElementType.FIELD) @ Retention (RetentionPolicy.RUNTIME) public @ interface SQLString {String name () default ""; Constraints constraints () default @ Constraints (primaryKey = true);}

In this way, we can use the self-defined "value"

Annotations do not support inheritance

We can't use extends to inherit a @ interface, but we can solve this problem in a nested way.

Collocation of AOP and annotations

"AOP" is no stranger to us in today's development, so what chemical reaction can be produced by "AOP" and "comments"? please take a look at the following code:

@ ApiLog:

@ Retention (RetentionPolicy.RUNTIME) @ Target ({ElementType.METHOD, ElementType.TYPE}) public @ interface ApiLog {/ * * Interface name * / String name ();}

Use:

@ GetMapping (value = "/ getConfig") @ ApiLog (name = "get system-related configurations") public Result getConfig () throws Exception {return sendOK (SystemService.getConfig (type));}

Aop uses:

@ Aspect @ Component public class SysLogAspect {@ Autowired private LogService logService; @ Pointcut ("@ annotation (cbuc.life.annotation.ApiLog)") public void logPointCut () {} @ Around ("logPointCut ()") public Object around (ProceedingJoinPoint point) throws Throwable {long beginTime = System.currentTimeMillis (); / / execute method Object result = point.proceed () / / execution duration (Ms) long time = System.currentTimeMillis ()-beginTime; / / Save log saveSysLog (point, time); return result;} private void saveSysLog (ProceedingJoinPoint joinPoint, long time) {MethodSignature signature = (MethodSignature) joinPoint.getSignature (); Method method = signature.getMethod (); LogEntity log = new LogEntity () ApiLog apiLog = method.getAnnotation (ApiLog.class); if (apiLog! = null) {/ / description log.setMethodDescribe (syslog.value ());} / / the method name of the request String className = joinPoint.getTarget (). GetClass (). GetName (); String methodName = signature.getName () Log.setMethod (className + "." + methodName + "()"); / / request parameters Object [] args = joinPoint.getArgs (); String params = JSON.toJSONString (args [0]); log.setParams (params); / / get request HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes ()) .getRequest () / / set the IP address log.setIp (ServletUtil.getIpAddress (request)); / / user name String username = LoginInfo.getUsername (); log.setUsername (username); / / Save Syslog logService.save (log);}} at this point, the study on "how to use annotations" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report