简体   繁体   中英

Pre-handle third party library method in Spring Boot

We are exploring Micrometer metrics collection library in Spring Boot 1.5.

Micrometer provides a static method in the Tag interface to create tags for metrics.

public interface Tag {
    String getKey();

    String getValue();

    static Tag of(String key, String value) {
        return new ImmutableTag(key, value);
    }
}

The implementation of ImmutableTag is as follows:

public class ImmutableTag implements Tag {
    private String key;
    private String value;

    public ImmutableTag(String key, String value) {
        requireNonNull(key);
        requireNonNull(value);
        this.key = key;
        this.value = value;
    }
...other methods...
}

Now, we are collecting some tags programmatically, and might end up with a null tag (which will throw an exception because of requireNonNull() ). But on encountering a null, we are okay with replacing the tag value with a default string (say "unknown").

What is the best way to handle this?

I have thought of the following:

  1. Try / Catch: Surround all such statements in a try/catch block. I understand this can be expensive and difficult to maintain.
  2. Handle null on our end: Check for any null tag being passed , and replace it with default string. However, we will have a lot of such statements, and want to have some sort of configuration that this happens by default.
  3. Wrapper interface: Create a TagWrapper interface , replace null with default value, and call the Tag.of() method. Seems like the best option to me now, however, when this is no longer needed (maybe a method like this is introduced later in the library later), getting rid of the wrapper will include a lot of changes.

Is there some configuration in Spring that allows me to pre-handle third-party library methods without creating a wrapper?

Maybe use Spring AOP. Something like:

@around(value="execution(* package.name.class.Tag.of)")
public void wrapTags(ProceedingJoinPoint call){
   try {
     Object[] args = call.getArgs();
     // wrap args in Optional.ofNullable
     call.proceed();
   } catch (Exception e){
      // handle exception
   }
}

You can try with add this properties:

in application.yml:

spring:
  jackson:
    deserialization:
      fail-on-null-creator-properties: false

or application.properties:

spring.jackson.deserialization.fail-on-null-creator-properties= false

I may be missing something, but can't you wrap the values in an Optional that are being passed to the Tag interface?

// wrapping values in Optional
public static String wrapTags(String s){
  return Optional.ofNullable(s).orElse("UNKNOWN");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM