The advantages and functions of annotations

  • Dynamically modifying properties
  • Dynamically add functionality (without invading the original code)
  • Dynamically change the execution logic

Spring Basic Configuration (skipped)

Developing definition annotations

Definition of annotations


@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Patch {
    String  key(a) default "";
    String  value(a) default "";
}

Copy the code

Annotations to realize


@Component
@Aspect
public class PatchAspect {

    @After("Patch()")
    public void after(JoinPoint joinPoint)  {
        // Record parameters
    }

    @AfterReturning(pointcut = "Patch()",returning="returnValue")
    public void afterJoinPoint(JoinPoint joinPoint ,Object returnValue){
        // Record the return value
    }


    @pointcut ("@annotation(annotation path)")
    public void patch(a){}

    @Around("Patch()")
    public void around(ProceedingJoinPoint joinPoint){
        try {

            StopWatch sw = new StopWatch();
            sw.start();
            // Get method parameters
            Object[] args = joinPoint.getArgs();
            MethodSignature sign = (MethodSignature) joinPoint.getSignature();
            String[] parameterNames = sign.getParameterNames();
            System.out.println("parameter list: ");
            for (int i = 0; i < parameterNames.length; i++) {
                System.out.println(parameterNames[i] + "=" + args[i]);
                // You can modify the corresponding parameter directly by using the parameter name and annotation value for interception or parameter verification

            }
            // Get the annotation parameter
            Patch annotation =  sign.getMethod().getAnnotation(Patch.class);
            System.out.println("value = " + annotation.value());
            System.out.println("key = " + annotation.key());

            /* / Annotations [][] annotations; try { annotations = pjp.getTarget().getClass(). getMethod(methodName, parameterTypes).getParameterAnnotations(); } catch (Exception e) { throw new SoftException(e); } * /

            // Execute method
            joinPoint.proceed();

            // method after execution logic
            sw.stop(args);
            System.out.println(sw.prettyPrint());

        } catch(Throwable throwable) { throwable.printStackTrace(); }}}Copy the code

conclusion

Annotations are essentially comments to the code, if there is no logic to implement parsing then just comments. There are two approaches to annotations, compile-direct scan and run-time reflection. Note: Java annotation-based development is different from the simple logic of dynamic languages, and often requires efficient handling of various types of judgments and unknowns in code.

For example, in Python, a similar function is called a decorator. The following implementation of a Python decorator might help you understand it better.


def run_time(func) :
    """Decorator for calculating function runtime. Arguments: func {function} Returns: function """

    def inner(*args, **kwargs) :
        start = time.time()
        res = func(*args, **kwargs)
        ret = time.time() - start
        if ret < 1e-6:
            unit = "ns"
            ret *= 1e9
        elif ret < 1e-3:
            unit = "us"
            ret *= 1e6
        elif ret < 1:
            unit = "ms"
            ret *= 1e3
        else:
            unit = "s"
        print("Total run time is %.1f %s\n" % (ret, unit))
        return res

    return inner

@run_time
def test() :
    pass

Copy the code

Business scenarios:

  1. Code performance analysis (log analysis input parameters, return values, and output function execution times)
  2. Business logging (unified business logging of code blocks with the same function)
  3. Uniform exception handling of code snippets
  4. Add additional logic to existing code (implemented without changing the code)

The resources

The fundamentals of JAVA annotations