理想很飽滿,現實很骨感。java
因爲業務須要「靈活可配置」的功能需求,在使用java開發Influxdb查詢功能的時候,遇到了一個問題,Measurement註解的名稱有可能須要動態變化。api
咱們先看下 @Measurement 註解的代碼:app
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;
問題能夠轉換爲:
-> 在@Measurement 註解生效以前,將變更的name值寫入。code
通過大概兩天時間的資料查找,發現了能夠經過:java反射去解決
主要須要操做如下兩個類的api繼承
java.lang.reflect.InvocationHandler; java.lang.reflect.Proxy;
最終解決方案,經過繼承 InfluxDBResultMapper 的 toPOJO 方法得以解決。
如下貼出代碼:flux
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); } }