Your development tool spring custom annotation

Time:2021-2-26

Your development tool spring custom annotation

preface

   custom annotation is a sharp tool in development, which is often used. It was mentioned in the last articleCustom verification notesThe usage of. However, recently received such a demand, mainly for some interfaces return data need to be encrypted. So it’s natural to think of itUser defined annotation + AOPTo achieve such a function. But for the user-defined annotation, it just stays on the surface and doesn’t do itKnow what it is, and know why it is. So this article is to understand the development tool of custom annotation.

What is a custom annotation?

Official definition

  An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.

Google translation

Annotations are a form of metadata that can be added to Java source code. Classes, methods, variables, parameters, and packages can all be annotated. Annotations have no direct effect on the operation of the annotated code.

After reading this definition, don’t be a bit confused. Don’t panic and practice to get true knowledge.

Create a custom annotation

   let’s first review the requirement scenario, which is to encrypt the data returned by XX interface. I talked about using it beforeUser defined annotation + AOPTo achieve this function. So let’s define an annotation calledEncryption, byEncryptionAfter modifying the interface with annotation, the returned data should be encrypted.

public @interface Encryption {
}

You’ll find that creating custom annotations is as easy as creating a normal interface. It’s just that the keywords used are different. On the underlying implementation, all defined annotations are automatically inherited java.lang.annotation . annotation interface.

Write the corresponding interface

@Encryption
@GetMapping("/encrypt")
public ResultVo encrypt(){
    return  ResultVoUtil.success ("different technology houses");
}

@GetMapping("/normal")
public ResultVo normal(){
    return  ResultVoUtil.success ("different technology houses");
}

Writing sections

@Around("@annotation(com.hxh.unified.param.check.annotation.Encryption)")
public ResultVo encryptPoint(ProceedingJoinPoint joinPoint) throws Throwable {
  ResultVo resultVo = (ResultVo) joinPoint.proceed();

  //Get comments
  MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  Method method = methodSignature.getMethod();
  Encryption annotation = method.getAnnotation(Encryption.class);

  //If it is identified, it is encrypted
  if(annotation != null){
    //Encryption
    String encrypt = EncryptUtil.encryptByAes(JSON.toJSONString(resultVo.getData()));
    resultVo.setData(encrypt);
  }

  return resultVo;
}

test result

Your development tool spring custom annotation

   at this time, you will find that the returned data is not encrypted. So why is this? As the saying goes, don’t panic when you encounter problems, take out your mobile phone and send it to a circle of friends (a little off topic). The reason for this is the lack of@Retentionyes@EncryptionLet’s add it.

@Retention(RetentionPolicy.RUNTIME)
public @interface Encryption {

}

Continue testing

Your development tool spring custom annotation

At this time, the returned data is encrypted, indicating that the custom annotation is effective.

Test common interface
Your development tool spring custom annotation

   it’s no use@EncryptionThe returned data is not encrypted. Now that the requirement has been realized, it’s time to understand the principle.

@Retention

@What is the role of retention

    retention is translated as “reservation”. This means that it is used to define the life cycle of annotations, and it needs to be specified when it is usedRetentionPolicyRetentionPolicyThere are three strategies

  • Source – the annotation is only kept in the source file. When a java file is compiled into a class file, the annotation is discarded.
  • Class – annotations are retained in the class file, but are discarded when the JVM loads the class file, which is the default life cycle.
  • Runtime – the annotation is not only saved in the class file, but also exists after the JVM loads the class file.

Choose the right life cycle

The first step is to define the life cycle: runtime > class > source. Generally, if you need to dynamically obtain annotation information at runtime, you can only use runtime. If you want to do some preprocessing operations at compile time, such as generating some auxiliary code, use class. If you only do some checking operations, such as @ override and @ suppresswarnings, you can choose source.

Our actual development of user-defined annotations are almost all using runtime

   at the beginning@EncryptionNot used@RetentionDefine its life cycle. Therefore, the AOP is always empty when it is obtained. If it is empty, the data will not be encrypted.

                  . Then give him something more, and one more@Target

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

}

@Target

  @TargetAnnotations limit where custom annotations can be used. This is the same as the parameter verification, the rules are agreed to prevent misuse and lead to problems. According to the above requirements, it can only be used in methods. According to different scenarios, it can be used in more places. For example, properties, packages, constructors, and so on.

  • Type – class, interface (including annotation type) or enumeration
  • Field – field (including enumeration constants)
  • Method – Method
  • Parameter – parameter
  • Constructor – constructor
  • LOCAL_ Variable – local variable
  • ANNOTATION_ Type – annotation type
  • Package – package
  • TYPE_ Parameter – type parameter
  • TYPE_ Use – type of use

The above two are commonly used meta annotations. Java provides a total of four meta annotations. You may ask, what is a meta annotation? The function of meta annotation is to annotate other annotations.

@Documented

  @DocumentedThe function of is to annotate the custom annotation. If you use@DocumentedAfter annotation, when Javadoc is generated, it will@DocumentedThe annotation is shown. It doesn’t have any practical effect. Just understand.

@Inherited

           @InheritedWhen a modified annotation is used on a parent class, its subclass also has the annotation. To put it simply, when the@InheritedModified notes@InheritedTestThe subclass that inherits it also has@InheritedTestNotes.

This can be talked about separately

Annotation element type

   referring to our experience in defining interfaces, we can define methods and constants in interfaces. But in custom annotation, there is only one thing to define: annotation type elementAnnotation type element

In fact, it can be simply understood that only methods can be defined, but it is different from methods in interfaces.

Note the following points when defining annotation type elements:

  • The access modifier must be public. If it is not written, it is public by default.
  • Element types can only be basic data type, string, class, enumeration type and annotation type.
  • Type () can’t define method parameters in parentheses. It’s just a special syntax. But it can be done throughdefaultKeyword to set the default value.
  • If there is no default value, the type element must be assigned a value when using annotations.

Continue to transform

Demand is always changing. The interfaces that need to be encrypted originally only use AES for encryption, but later some interfaces are told to use des for encryption. In view of this situation, we can add a configuration item in the annotation to select the encryption method.

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

    /**
     *Encryption type
     */
    String value() default "AES";
  
}

Adjust the interface

@Encryption
@GetMapping("/encrypt")
public ResultVo encrypt(){
    return  ResultVoUtil.success ("different technology houses");
}

@Encryption(value = "DES")
@GetMapping("/encryptDes")
public ResultVo encryptDes(){
    return  ResultVoUtil.success ("different technology houses");
}

@GetMapping("/normal")
public ResultVo normal(){
    return  ResultVoUtil.success ("different technology houses");
}

Adjust AOP

@Around("@annotation(com.hxh.unified.param.check.annotation.Encryption)")
public ResultVo encryptPoint(ProceedingJoinPoint joinPoint) throws Throwable {
  ResultVo resultVo = (ResultVo) joinPoint.proceed();

  //Get comments
  MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  Method method = methodSignature.getMethod();
  Encryption annotation = method.getAnnotation(Encryption.class);

  //If it is identified, it is encrypted
  if(annotation != null){
    //Encryption
    String encrypt = null;
    switch (annotation.value()){
      case "AES":
        encrypt = EncryptUtil.encryptByAes(JSON.toJSONString(resultVo.getData()));
        break;
      case "DES":
        encrypt = EncryptUtil.encryptByDes(JSON.toJSONString(resultVo.getData()));
        break;
      default:
        break;
    }
    resultVo.setData(encrypt);
  }

  return resultVo;
}

                . You can find annotation element types,When used, manipulating element types is like manipulating attributes. When parsing, operating element types is like operating methods.

antic

  • When the annotation has no annotation type element, it can be written as@Encryptionand@Encryption()Equivalent.
  • When an annotation has only one annotation type element and the name is value. when in use@Encryption("DES")and@Encryption(value = "DES")Equivalent.

Points to note

  • You need to specify the life cycle of the annotation according to the actual situation@Retention
  • use@TargetTo limit the scope of the use of annotations and prevent annotations from being misused.
  • If the annotation is configured on the method, we need to get it from the method object. If it is configured on an attribute, it needs to be obtained from the field object corresponding to the attribute. In a word, you can get it wherever you use it.

summary

An annotation can be understood as an identifier. The key nodes in the program code can be marked with these marks, which will not change the execution logic of the original code. Then the program can detect these tags at compile time or run time and make corresponding operations. Combined with the above scenario, we can get the basic process of using custom annotation

  1. Define annotation — create according to the business.
  2. Use annotation — > to use in the corresponding code.
  3. Parsing annotations — tags are detected at compile time or run time and special operations are performed.

Review of last issue

ending

If you think it is helpful to you, you can comment more, like more, or go to my home page to have a look. Maybe there are articles you like, or you can pay attention to them. Thank you.

I’m a different technology house, making a little progress every day and experiencing a different life. See you next time!

Recommended Today

Deeply analyze the principle and practice of RSA key

1、 Preface After experiencing many dark moments in life, when you read this article, you will regret and even be angry: why didn’t you write this article earlier?! Your darkest moments include: 1. Your project needs to be connected with the bank, and the other party needs you to provide an encryption certificate. You have […]