Ideals are full and reality is skeletal.
Because the business needs "flexible and configurable" functional requirements, when using java to develop the query function of Influxdb, there is a problem that the name of Measurement annotation may need to change dynamically.
Let's first look at the code for the @Measurement annotation:
package org.influxdb.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; /** * @author fmachado */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Measurement { String name(); String database() default "[unassigned]"; String retentionPolicy() default "autogen"; TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
The problem can be converted to:
-> Write the changed name value before the @Measurement annotation takes effect.
After searching for data for about two days, it was found that it could be solved by: java reflection.
The main need is to operate on the api of the following two classes
java.lang.reflect.InvocationHandler; java.lang.reflect.Proxy;
The final solution is solved by inheriting the toPOJO method of InfluxDBResultMapper.
The following code is posted:
public class InfluxDBResultMapperHelper extends InfluxDBResultMapper { public <T> List<T> toPOJO(final QueryResult queryResult, final Class<T> clazz,String name) throws InfluxDBMapperException { InvocationHandler handler = Proxy.getInvocationHandler(clazz.getAnnotation(Measurement.class)); Field hField = null; try { hField = handler.getClass().getDeclaredField(ME_VALUE); hField.setAccessible(true); Map memberValues = (Map) hField.get(handler); memberValues.put(ME_NAME, name); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return toPOJO(queryResult, clazz, TimeUnit.MILLISECONDS); } }