ConvertColumnHandler优化
This commit is contained in:
@@ -29,7 +29,6 @@ import org.redkale.cluster.spi.ClusterModuleEngine;
|
||||
import org.redkale.cluster.spi.HttpClusterRpcClient;
|
||||
import org.redkale.cluster.spi.HttpLocalRpcClient;
|
||||
import org.redkale.convert.Convert;
|
||||
import org.redkale.convert.ConvertColumnTransfer;
|
||||
import org.redkale.convert.bson.BsonFactory;
|
||||
import org.redkale.convert.json.*;
|
||||
import org.redkale.convert.proto.ProtobufFactory;
|
||||
@@ -304,10 +303,9 @@ public final class Application {
|
||||
"jsonconvert", Convert.class, JsonFactory.root().getConvert());
|
||||
this.resourceFactory.register(
|
||||
"protobufconvert", Convert.class, ProtobufFactory.root().getConvert());
|
||||
Consumer<ConvertColumnTransfer> transferConsumer = resourceFactory::inject;
|
||||
BsonFactory.root().registerTransferConsumer(transferConsumer);
|
||||
JsonFactory.root().registerTransferConsumer(transferConsumer);
|
||||
ProtobufFactory.root().registerTransferConsumer(transferConsumer);
|
||||
BsonFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
|
||||
JsonFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
|
||||
ProtobufFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
|
||||
|
||||
// 系统内部模块组件
|
||||
moduleEngines.add(this.sourceModule); // 放第一,很多module依赖于source
|
||||
|
||||
@@ -50,15 +50,6 @@ public @interface ConvertColumn {
|
||||
*/
|
||||
ConvertType type() default ConvertType.ALL;
|
||||
|
||||
/**
|
||||
* 字段值转换器
|
||||
*
|
||||
* @return ConvertColumnTransfer实现类
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
Class<? extends ConvertColumnTransfer> tranfer() default ConvertColumnTransfer.class;
|
||||
|
||||
/**
|
||||
* ConvertColumn 的多用类
|
||||
*
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
package org.redkale.convert;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* ConvertColumn 对应的实体类
|
||||
*
|
||||
@@ -22,17 +24,17 @@ public final class ConvertColumnEntry {
|
||||
|
||||
private ConvertType convertType;
|
||||
|
||||
private ConvertColumnTransfer transfer;
|
||||
private BiFunction<?, String, ?> fieldFunc;
|
||||
|
||||
public ConvertColumnEntry() {}
|
||||
|
||||
public ConvertColumnEntry(ConvertColumn column, ConvertColumnTransfer transfer) {
|
||||
public ConvertColumnEntry(ConvertColumn column, BiFunction<?, String, ?> fieldFunc) {
|
||||
if (column == null) return;
|
||||
this.name = column.name();
|
||||
this.index = column.index();
|
||||
this.ignore = column.ignore();
|
||||
this.convertType = column.type();
|
||||
this.transfer = transfer;
|
||||
this.fieldFunc = fieldFunc;
|
||||
}
|
||||
|
||||
public ConvertColumnEntry(String name) {
|
||||
@@ -51,6 +53,14 @@ public final class ConvertColumnEntry {
|
||||
this.convertType = convertType;
|
||||
}
|
||||
|
||||
public ConvertColumnEntry(
|
||||
String name, boolean ignore, ConvertType convertType, BiFunction<?, String, ?> fieldFunc) {
|
||||
this.name = name;
|
||||
this.ignore = ignore;
|
||||
this.convertType = convertType;
|
||||
this.fieldFunc = fieldFunc;
|
||||
}
|
||||
|
||||
public ConvertColumnEntry(String name, int index, boolean ignore, ConvertType convertType) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
@@ -59,16 +69,16 @@ public final class ConvertColumnEntry {
|
||||
}
|
||||
|
||||
public ConvertColumnEntry(
|
||||
String name, int index, boolean ignore, ConvertType convertType, ConvertColumnTransfer transfer) {
|
||||
String name, int index, boolean ignore, ConvertType convertType, BiFunction<?, String, ?> fieldFunc) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.ignore = ignore;
|
||||
this.convertType = convertType;
|
||||
this.transfer = transfer;
|
||||
this.fieldFunc = fieldFunc;
|
||||
}
|
||||
|
||||
public ConvertColumnTransfer transfer() {
|
||||
return transfer;
|
||||
public BiFunction<?, String, ?> fieldFunc() {
|
||||
return fieldFunc;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
|
||||
59
src/main/java/org/redkale/convert/ConvertColumnHandler.java
Normal file
59
src/main/java/org/redkale/convert/ConvertColumnHandler.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.convert;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* 字段值转换器,常见于脱敏操作
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
*
|
||||
*/
|
||||
@Documented
|
||||
@Target({METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
@Repeatable(ConvertColumnHandler.ConvertColumnHandlers.class)
|
||||
public @interface ConvertColumnHandler {
|
||||
|
||||
/**
|
||||
* 字段值转换器
|
||||
*
|
||||
* @return BiFunction<String, Object, Object>实现类
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
Class<? extends BiFunction> value() default BiFunction.class;
|
||||
|
||||
/**
|
||||
* 解析/序列化定制化的TYPE
|
||||
*
|
||||
* @return JSON or BSON or ALL
|
||||
*/
|
||||
ConvertType type() default ConvertType.ALL;
|
||||
|
||||
/**
|
||||
* ConvertColumnHandler 的多用类
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@Documented
|
||||
@Target({METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
public static @interface ConvertColumnHandlers {
|
||||
|
||||
ConvertColumnHandler[] value();
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.convert;
|
||||
|
||||
/**
|
||||
* 字段值转换器,常见于脱敏操作
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param <F> 字段类型
|
||||
*/
|
||||
public interface ConvertColumnTransfer<F> {
|
||||
|
||||
/**
|
||||
* 字段值转换
|
||||
*
|
||||
* @param obj 父对象
|
||||
* @param field 字段名
|
||||
* @param value 字段值
|
||||
*
|
||||
* @return Object
|
||||
*/
|
||||
public Object transfer(Object obj, String field, F value);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.*;
|
||||
@@ -60,7 +61,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
|
||||
private final ConcurrentHashMap<AccessibleObject, ConvertColumnEntry> columnEntrys = new ConcurrentHashMap();
|
||||
|
||||
private final ConcurrentHashMap<Class, ConvertColumnTransfer> transfers = new ConcurrentHashMap();
|
||||
private final ConcurrentHashMap<Class, BiFunction> columnHandlers = new ConcurrentHashMap();
|
||||
|
||||
private final Set<Class> skipIgnores = new HashSet();
|
||||
|
||||
@@ -73,7 +74,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
|
||||
private boolean skipAllIgnore = false;
|
||||
|
||||
private Consumer<ConvertColumnTransfer> transferConsumer;
|
||||
private Consumer<BiFunction> columnHandlerConsumer;
|
||||
|
||||
protected ConvertFactory(ConvertFactory<R, W> parent, int features) {
|
||||
this.features = features;
|
||||
@@ -414,8 +415,49 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
return en;
|
||||
}
|
||||
final ConvertType ct = this.getConvertType();
|
||||
ConvertColumn[] ccs = element.getAnnotationsByType(ConvertColumn.class);
|
||||
String fieldName = null;
|
||||
// 解析 ColumnHandler
|
||||
BiFunction colHandler = null;
|
||||
ConvertType colConvertType = ConvertType.ALL;
|
||||
ConvertColumnHandler[] chs = element.getAnnotationsByType(ConvertColumnHandler.class);
|
||||
if (chs.length == 0 && element instanceof Method) {
|
||||
final Method method = (Method) element;
|
||||
fieldName = readGetSetFieldName(method);
|
||||
if (fieldName != null) {
|
||||
Class mclz = method.getDeclaringClass();
|
||||
do {
|
||||
try {
|
||||
chs = mclz.getDeclaredField(fieldName).getAnnotationsByType(ConvertColumnHandler.class);
|
||||
break;
|
||||
} catch (Exception e) { // 说明没有该字段,忽略异常
|
||||
}
|
||||
} while (mclz != Object.class && (mclz = mclz.getSuperclass()) != Object.class);
|
||||
}
|
||||
}
|
||||
for (ConvertColumnHandler h : chs) {
|
||||
if (h.type().contains(ct)) {
|
||||
Class<? extends BiFunction> handlerClass = h.value();
|
||||
if (handlerClass != BiFunction.class) {
|
||||
colConvertType = h.type();
|
||||
colHandler = findColumnHandler(handlerClass);
|
||||
if (colHandler == null) {
|
||||
try {
|
||||
colHandler = handlerClass.getConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(e);
|
||||
}
|
||||
Consumer<BiFunction> consumer = findColumnHandlerConsumer();
|
||||
if (consumer != null) {
|
||||
consumer.accept(colHandler);
|
||||
}
|
||||
register((Class) handlerClass, colHandler);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 解析ConvertColumn
|
||||
ConvertColumn[] ccs = element.getAnnotationsByType(ConvertColumn.class);
|
||||
if (ccs.length == 0 && element instanceof Method) {
|
||||
final Method method = (Method) element;
|
||||
fieldName = readGetSetFieldName(method);
|
||||
@@ -439,7 +481,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
}
|
||||
if (ccs.length == 0 && onlyColumns != null && fieldName != null) {
|
||||
if (!onlyColumns.contains(fieldName)) {
|
||||
return new ConvertColumnEntry(fieldName, true);
|
||||
return new ConvertColumnEntry(fieldName, true, colConvertType, colHandler);
|
||||
}
|
||||
}
|
||||
for (ConvertColumn ref : ccs) {
|
||||
@@ -447,27 +489,10 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
String realName = ref.name().isEmpty() ? fieldName : ref.name();
|
||||
if (onlyColumns != null && fieldName != null) {
|
||||
if (!onlyColumns.contains(realName)) {
|
||||
return new ConvertColumnEntry(realName, true);
|
||||
return new ConvertColumnEntry(realName, true, colConvertType, colHandler);
|
||||
}
|
||||
}
|
||||
ConvertColumnTransfer transfer = null;
|
||||
Class<? extends ConvertColumnTransfer> transferClass = ref.tranfer();
|
||||
if (transferClass != ConvertColumnTransfer.class) {
|
||||
transfer = findTransfer(transferClass);
|
||||
if (transfer == null) {
|
||||
try {
|
||||
transfer = transferClass.getConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ConvertException(e);
|
||||
}
|
||||
Consumer<ConvertColumnTransfer> consumer = findTransferConsumer();
|
||||
if (consumer != null) {
|
||||
consumer.accept(transfer);
|
||||
}
|
||||
register((Class) transferClass, transfer);
|
||||
}
|
||||
}
|
||||
ConvertColumnEntry entry = new ConvertColumnEntry(ref, transfer);
|
||||
ConvertColumnEntry entry = new ConvertColumnEntry(ref, colHandler);
|
||||
if (skipAllIgnore) {
|
||||
entry.setIgnore(false);
|
||||
return entry;
|
||||
@@ -484,6 +509,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
if (colHandler != null) {
|
||||
return new ConvertColumnEntry(fieldName, false, colConvertType, colHandler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -890,11 +918,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
return child;
|
||||
}
|
||||
|
||||
private Consumer<ConvertColumnTransfer> findTransferConsumer() {
|
||||
if (transferConsumer != null) {
|
||||
return transferConsumer;
|
||||
private Consumer<BiFunction> findColumnHandlerConsumer() {
|
||||
if (columnHandlerConsumer != null) {
|
||||
return columnHandlerConsumer;
|
||||
}
|
||||
return parent == null ? null : parent.findTransferConsumer();
|
||||
return parent == null ? null : parent.findColumnHandlerConsumer();
|
||||
}
|
||||
|
||||
private Class findEntityAlias(String name) {
|
||||
@@ -903,12 +931,12 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ConvertColumnTransfer初始化的处理函数
|
||||
* 设置ColumnHandler初始化的处理函数
|
||||
*
|
||||
* @param consumer ConvertColumnTransfer处理函数
|
||||
* @param consumer ColumnHandler处理函数
|
||||
*/
|
||||
public final void registerTransferConsumer(Consumer<ConvertColumnTransfer> consumer) {
|
||||
this.transferConsumer = consumer;
|
||||
public final void registerColumnHandlerConsumer(Consumer<BiFunction> consumer) {
|
||||
this.columnHandlerConsumer = consumer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1082,12 +1110,12 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public final <C extends ConvertColumnTransfer> ConvertColumnTransfer findTransfer(Class<C> type) {
|
||||
ConvertColumnTransfer transfer = transfers.get(type);
|
||||
if (transfer != null) {
|
||||
return transfer;
|
||||
public final <C extends BiFunction> BiFunction findColumnHandler(Class<C> type) {
|
||||
BiFunction handler = columnHandlers.get(type);
|
||||
if (handler != null) {
|
||||
return handler;
|
||||
}
|
||||
return this.parent == null ? null : this.parent.findTransfer(type);
|
||||
return this.parent == null ? null : this.parent.findColumnHandler(type);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -1095,8 +1123,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
return (Encodeable<W, E>) anyEncoder;
|
||||
}
|
||||
|
||||
public final <C extends ConvertColumnTransfer> void register(final Class<C> clazz, final C transfer) {
|
||||
transfers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(transfer));
|
||||
public final <C extends BiFunction> void register(Class<C> clazz, C columnHandler) {
|
||||
columnHandlers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(columnHandler));
|
||||
}
|
||||
|
||||
public final <E> void register(final Type clazz, final SimpledCoder<R, W, E> coder) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.redkale.convert;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.function.BiFunction;
|
||||
import org.redkale.annotation.Comment;
|
||||
import org.redkale.util.Attribute;
|
||||
|
||||
@@ -41,7 +42,7 @@ public final class EnMember<W extends Writer, T, F> {
|
||||
|
||||
final Method method; // 对应类成员的Method也可能为null
|
||||
|
||||
final ConvertColumnTransfer transfer; // 一般为null
|
||||
final BiFunction<String, Object, Object> fieldFunc; // 一般为null
|
||||
|
||||
int index;
|
||||
|
||||
@@ -50,16 +51,12 @@ public final class EnMember<W extends Writer, T, F> {
|
||||
int tag; // 主要给protobuf使用
|
||||
|
||||
public EnMember(
|
||||
Attribute<T, F> attribute,
|
||||
Encodeable<W, F> encoder,
|
||||
Field field,
|
||||
Method method,
|
||||
ConvertColumnTransfer transfer) {
|
||||
Attribute<T, F> attribute, Encodeable<W, F> encoder, Field field, Method method, BiFunction fieldFunc) {
|
||||
this.attribute = attribute;
|
||||
this.encoder = encoder;
|
||||
this.field = field;
|
||||
this.method = method;
|
||||
this.transfer = transfer;
|
||||
this.fieldFunc = fieldFunc;
|
||||
Class t = attribute.type();
|
||||
this.string = CharSequence.class.isAssignableFrom(t);
|
||||
this.bool = t == Boolean.class || t == boolean.class;
|
||||
@@ -106,8 +103,8 @@ public final class EnMember<W extends Writer, T, F> {
|
||||
|
||||
public Object getFieldValue(T obj) {
|
||||
F val = attribute.get(obj);
|
||||
if (transfer != null) {
|
||||
return transfer.transfer(obj, attribute.field(), val);
|
||||
if (fieldFunc != null) {
|
||||
return fieldFunc.apply(attribute.field(), val);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
fieldCoder,
|
||||
field,
|
||||
null,
|
||||
ref == null ? null : ref.transfer());
|
||||
ref == null ? null : ref.fieldFunc());
|
||||
if (ref != null) {
|
||||
member.index = ref.getIndex();
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
fieldCoder,
|
||||
maybeField,
|
||||
method,
|
||||
ref == null ? null : ref.transfer());
|
||||
ref == null ? null : ref.fieldFunc());
|
||||
if (Utility.contains(list, m -> m.attribute.field().equals(member.attribute.field()))) {
|
||||
continue;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
null,
|
||||
f,
|
||||
null,
|
||||
ref2 == null ? null : ref2.transfer());
|
||||
ref2 == null ? null : ref2.fieldFunc());
|
||||
if (ref2 != null) {
|
||||
member.index = ref2.getIndex();
|
||||
}
|
||||
@@ -251,7 +251,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ref2 == null ? null : ref2.transfer());
|
||||
ref2 == null ? null : ref2.fieldFunc());
|
||||
if (ref2 != null) {
|
||||
member.index = ref2.getIndex();
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
||||
if (ref != null && ref.ignore()) {
|
||||
continue;
|
||||
}
|
||||
if (ref != null && ref.transfer() != null) {
|
||||
if (ref != null && ref.fieldFunc() != null) {
|
||||
return null;
|
||||
}
|
||||
if (!(checkMemberType(factory, clazz, method.getGenericReturnType(), method.getReturnType()))) {
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
|
||||
package org.redkale.test.convert;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.redkale.convert.ConvertColumn;
|
||||
import org.redkale.convert.ConvertColumnTransfer;
|
||||
import org.redkale.convert.ConvertColumnHandler;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class ConvertTransferTest {
|
||||
public class ConvertColumnHandlerTest {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
ConvertTransferTest test = new ConvertTransferTest();
|
||||
ConvertColumnHandlerTest test = new ConvertColumnHandlerTest();
|
||||
test.run1();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ConvertTransferTest {
|
||||
|
||||
private String name;
|
||||
|
||||
@ConvertColumn(tranfer = ParamTransfer.class)
|
||||
@ConvertColumnHandler(ParamColumnHandler.class)
|
||||
private String phone;
|
||||
|
||||
public String getName() {
|
||||
@@ -57,10 +57,10 @@ public class ConvertTransferTest {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ParamTransfer implements ConvertColumnTransfer<String> {
|
||||
public static class ParamColumnHandler implements BiFunction<String, String, String> {
|
||||
|
||||
@Override
|
||||
public Object transfer(Object obj, String field, String value) {
|
||||
public String apply(String field, String value) {
|
||||
if (value == null || value.length() < 5) {
|
||||
return value;
|
||||
} else {
|
||||
Reference in New Issue
Block a user