在开发中,元数据一般结构为:
module/group:code1-value1;code2-value2; ...
比如:sex:0-男;1-女
对于处理这个问题,每个团队都有自己的处理方式,这边我也提供一个方式供大家参考:
1、我提供了一个注解;
设置提供了两个值,一个是所属module/group,另一个是自定义的属性名:
如果在实体类中 用sex=0|1表示 性别code,用sexDescr表示value=男|女,那么fieldName应该设置为sexDescr。
2、提供了一个PairAware的接口
里面有个getPairs的default方式,很明显了,就是通过Java新特性里面的default方法做文章:方法实现很简单,遍历this(即实现PairAware)的属性,找到被Pair注解的属性,根据module和此属性的值,从元属性中查找到对应的值,然后以fieldName为key放入map中。通过调用getPairs()方法获取到这个map。
3、效果
4、完整代码:
1)Pair
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pair {
public String module();
/** 显示值的key */
public String fieldName();
}
2)PairAware
public interface PairAware {
public default Map<Object, Object> getPairs() {
Map<Object, Object> pairs = new HashMap<>();
Field[] fields = getClass().getDeclaredFields();
for (Field f : fields) {
Pair pair = f.getDeclaredAnnotation(Pair.class);
if (Objects.nonNull(pair)) {
Object key = fieldValue(f);
String module = pair.module();
if (pairs.containsKey(pair.fieldName())) {
throw new RuntimeException("[fieldName:" + pair.fieldName() + "]重复");
}
pairs.put(pair.fieldName(), value(module, key));
}
}
return pairs;
}
default String value(String module, Object key) {
return PairMapping.value(module, key);
}
default Object fieldValue(Field field) {
if (Objects.nonNull(field)) {
field.setAccessible(true);
try {
return field.get(this);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
} finally {
field.setAccessible(false);
}
}
return null;
}
}
3)PairMapping (缓存容器)
public class PairMapping {
private static Map<String, Map<Object, String>> vessel;
private PairMapping() {
}
public static String value(String module, Object key) {
return Optional.ofNullable(vessel.get(module)).map(m -> m.get(key)).orElse(null);
}
public static void source(Supplier<Map<String, Map<Object, String>>> supplier) {
vessel = Optional.ofNullable(supplier).map(s -> s.get()).orElse(null);
}
public static void partSource(String module, Supplier<Map<Object, String>> supplier) {
vessel = Optional.ofNullable(vessel).orElseGet(HashMap::new);
Map<Object, String> part = Optional.ofNullable(supplier).map(s -> s.get()).orElse(null);
vessel.put(module, part);
}
}