ConvertColumnHandler优化

This commit is contained in:
redkale
2024-06-04 17:26:15 +08:00
parent 3819e42593
commit 19041335b4
10 changed files with 163 additions and 109 deletions

View File

@@ -29,7 +29,6 @@ import org.redkale.cluster.spi.ClusterModuleEngine;
import org.redkale.cluster.spi.HttpClusterRpcClient; import org.redkale.cluster.spi.HttpClusterRpcClient;
import org.redkale.cluster.spi.HttpLocalRpcClient; import org.redkale.cluster.spi.HttpLocalRpcClient;
import org.redkale.convert.Convert; import org.redkale.convert.Convert;
import org.redkale.convert.ConvertColumnTransfer;
import org.redkale.convert.bson.BsonFactory; import org.redkale.convert.bson.BsonFactory;
import org.redkale.convert.json.*; import org.redkale.convert.json.*;
import org.redkale.convert.proto.ProtobufFactory; import org.redkale.convert.proto.ProtobufFactory;
@@ -304,10 +303,9 @@ public final class Application {
"jsonconvert", Convert.class, JsonFactory.root().getConvert()); "jsonconvert", Convert.class, JsonFactory.root().getConvert());
this.resourceFactory.register( this.resourceFactory.register(
"protobufconvert", Convert.class, ProtobufFactory.root().getConvert()); "protobufconvert", Convert.class, ProtobufFactory.root().getConvert());
Consumer<ConvertColumnTransfer> transferConsumer = resourceFactory::inject; BsonFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
BsonFactory.root().registerTransferConsumer(transferConsumer); JsonFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
JsonFactory.root().registerTransferConsumer(transferConsumer); ProtobufFactory.root().registerColumnHandlerConsumer(resourceFactory::inject);
ProtobufFactory.root().registerTransferConsumer(transferConsumer);
// 系统内部模块组件 // 系统内部模块组件
moduleEngines.add(this.sourceModule); // 放第一很多module依赖于source moduleEngines.add(this.sourceModule); // 放第一很多module依赖于source

View File

@@ -50,15 +50,6 @@ public @interface ConvertColumn {
*/ */
ConvertType type() default ConvertType.ALL; ConvertType type() default ConvertType.ALL;
/**
* 字段值转换器
*
* @return ConvertColumnTransfer实现类
*
* @since 2.8.0
*/
Class<? extends ConvertColumnTransfer> tranfer() default ConvertColumnTransfer.class;
/** /**
* ConvertColumn 的多用类 * ConvertColumn 的多用类
* *

View File

@@ -5,6 +5,8 @@
*/ */
package org.redkale.convert; package org.redkale.convert;
import java.util.function.BiFunction;
/** /**
* ConvertColumn 对应的实体类 * ConvertColumn 对应的实体类
* *
@@ -22,17 +24,17 @@ public final class ConvertColumnEntry {
private ConvertType convertType; private ConvertType convertType;
private ConvertColumnTransfer transfer; private BiFunction<?, String, ?> fieldFunc;
public ConvertColumnEntry() {} public ConvertColumnEntry() {}
public ConvertColumnEntry(ConvertColumn column, ConvertColumnTransfer transfer) { public ConvertColumnEntry(ConvertColumn column, BiFunction<?, String, ?> fieldFunc) {
if (column == null) return; if (column == null) return;
this.name = column.name(); this.name = column.name();
this.index = column.index(); this.index = column.index();
this.ignore = column.ignore(); this.ignore = column.ignore();
this.convertType = column.type(); this.convertType = column.type();
this.transfer = transfer; this.fieldFunc = fieldFunc;
} }
public ConvertColumnEntry(String name) { public ConvertColumnEntry(String name) {
@@ -51,6 +53,14 @@ public final class ConvertColumnEntry {
this.convertType = convertType; 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) { public ConvertColumnEntry(String name, int index, boolean ignore, ConvertType convertType) {
this.name = name; this.name = name;
this.index = index; this.index = index;
@@ -59,16 +69,16 @@ public final class ConvertColumnEntry {
} }
public 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.name = name;
this.index = index; this.index = index;
this.ignore = ignore; this.ignore = ignore;
this.convertType = convertType; this.convertType = convertType;
this.transfer = transfer; this.fieldFunc = fieldFunc;
} }
public ConvertColumnTransfer transfer() { public BiFunction<?, String, ?> fieldFunc() {
return transfer; return fieldFunc;
} }
public String name() { public String name() {

View 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&lt;String, Object, Object&gt;实现类
*
* @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();
}
}

View File

@@ -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);
}

View File

@@ -15,6 +15,7 @@ import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.*; 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<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(); 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 boolean skipAllIgnore = false;
private Consumer<ConvertColumnTransfer> transferConsumer; private Consumer<BiFunction> columnHandlerConsumer;
protected ConvertFactory(ConvertFactory<R, W> parent, int features) { protected ConvertFactory(ConvertFactory<R, W> parent, int features) {
this.features = features; this.features = features;
@@ -414,8 +415,49 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
return en; return en;
} }
final ConvertType ct = this.getConvertType(); final ConvertType ct = this.getConvertType();
ConvertColumn[] ccs = element.getAnnotationsByType(ConvertColumn.class);
String fieldName = null; 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) { if (ccs.length == 0 && element instanceof Method) {
final Method method = (Method) element; final Method method = (Method) element;
fieldName = readGetSetFieldName(method); 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 (ccs.length == 0 && onlyColumns != null && fieldName != null) {
if (!onlyColumns.contains(fieldName)) { if (!onlyColumns.contains(fieldName)) {
return new ConvertColumnEntry(fieldName, true); return new ConvertColumnEntry(fieldName, true, colConvertType, colHandler);
} }
} }
for (ConvertColumn ref : ccs) { 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(); String realName = ref.name().isEmpty() ? fieldName : ref.name();
if (onlyColumns != null && fieldName != null) { if (onlyColumns != null && fieldName != null) {
if (!onlyColumns.contains(realName)) { if (!onlyColumns.contains(realName)) {
return new ConvertColumnEntry(realName, true); return new ConvertColumnEntry(realName, true, colConvertType, colHandler);
} }
} }
ConvertColumnTransfer transfer = null; ConvertColumnEntry entry = new ConvertColumnEntry(ref, colHandler);
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);
if (skipAllIgnore) { if (skipAllIgnore) {
entry.setIgnore(false); entry.setIgnore(false);
return entry; return entry;
@@ -484,6 +509,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
return entry; return entry;
} }
} }
if (colHandler != null) {
return new ConvertColumnEntry(fieldName, false, colConvertType, colHandler);
}
return null; return null;
} }
@@ -890,11 +918,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
return child; return child;
} }
private Consumer<ConvertColumnTransfer> findTransferConsumer() { private Consumer<BiFunction> findColumnHandlerConsumer() {
if (transferConsumer != null) { if (columnHandlerConsumer != null) {
return transferConsumer; return columnHandlerConsumer;
} }
return parent == null ? null : parent.findTransferConsumer(); return parent == null ? null : parent.findColumnHandlerConsumer();
} }
private Class findEntityAlias(String name) { 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) { public final void registerColumnHandlerConsumer(Consumer<BiFunction> consumer) {
this.transferConsumer = consumer; this.columnHandlerConsumer = consumer;
} }
/** /**
@@ -1082,12 +1110,12 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
return result; return result;
} }
public final <C extends ConvertColumnTransfer> ConvertColumnTransfer findTransfer(Class<C> type) { public final <C extends BiFunction> BiFunction findColumnHandler(Class<C> type) {
ConvertColumnTransfer transfer = transfers.get(type); BiFunction handler = columnHandlers.get(type);
if (transfer != null) { if (handler != null) {
return transfer; 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; return (Encodeable<W, E>) anyEncoder;
} }
public final <C extends ConvertColumnTransfer> void register(final Class<C> clazz, final C transfer) { public final <C extends BiFunction> void register(Class<C> clazz, C columnHandler) {
transfers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(transfer)); columnHandlers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(columnHandler));
} }
public final <E> void register(final Type clazz, final SimpledCoder<R, W, E> coder) { public final <E> void register(final Type clazz, final SimpledCoder<R, W, E> coder) {

View File

@@ -6,6 +6,7 @@
package org.redkale.convert; package org.redkale.convert;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.function.BiFunction;
import org.redkale.annotation.Comment; import org.redkale.annotation.Comment;
import org.redkale.util.Attribute; import org.redkale.util.Attribute;
@@ -41,7 +42,7 @@ public final class EnMember<W extends Writer, T, F> {
final Method method; // 对应类成员的Method也可能为null final Method method; // 对应类成员的Method也可能为null
final ConvertColumnTransfer transfer; // 一般为null final BiFunction<String, Object, Object> fieldFunc; // 一般为null
int index; int index;
@@ -50,16 +51,12 @@ public final class EnMember<W extends Writer, T, F> {
int tag; // 主要给protobuf使用 int tag; // 主要给protobuf使用
public EnMember( public EnMember(
Attribute<T, F> attribute, Attribute<T, F> attribute, Encodeable<W, F> encoder, Field field, Method method, BiFunction fieldFunc) {
Encodeable<W, F> encoder,
Field field,
Method method,
ConvertColumnTransfer transfer) {
this.attribute = attribute; this.attribute = attribute;
this.encoder = encoder; this.encoder = encoder;
this.field = field; this.field = field;
this.method = method; this.method = method;
this.transfer = transfer; this.fieldFunc = fieldFunc;
Class t = attribute.type(); Class t = attribute.type();
this.string = CharSequence.class.isAssignableFrom(t); this.string = CharSequence.class.isAssignableFrom(t);
this.bool = t == Boolean.class || t == boolean.class; 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) { public Object getFieldValue(T obj) {
F val = attribute.get(obj); F val = attribute.get(obj);
if (transfer != null) { if (fieldFunc != null) {
return transfer.transfer(obj, attribute.field(), val); return fieldFunc.apply(attribute.field(), val);
} else { } else {
return val; return val;
} }

View File

@@ -110,7 +110,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
fieldCoder, fieldCoder,
field, field,
null, null,
ref == null ? null : ref.transfer()); ref == null ? null : ref.fieldFunc());
if (ref != null) { if (ref != null) {
member.index = ref.getIndex(); member.index = ref.getIndex();
} }
@@ -194,7 +194,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
fieldCoder, fieldCoder,
maybeField, maybeField,
method, method,
ref == null ? null : ref.transfer()); ref == null ? null : ref.fieldFunc());
if (Utility.contains(list, m -> m.attribute.field().equals(member.attribute.field()))) { if (Utility.contains(list, m -> m.attribute.field().equals(member.attribute.field()))) {
continue; continue;
} }
@@ -223,7 +223,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
null, null,
f, f,
null, null,
ref2 == null ? null : ref2.transfer()); ref2 == null ? null : ref2.fieldFunc());
if (ref2 != null) { if (ref2 != null) {
member.index = ref2.getIndex(); member.index = ref2.getIndex();
} }
@@ -251,7 +251,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
null, null,
null, null,
null, null,
ref2 == null ? null : ref2.transfer()); ref2 == null ? null : ref2.fieldFunc());
if (ref2 != null) { if (ref2 != null) {
member.index = ref2.getIndex(); member.index = ref2.getIndex();
} }

View File

@@ -257,7 +257,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
if (ref != null && ref.ignore()) { if (ref != null && ref.ignore()) {
continue; continue;
} }
if (ref != null && ref.transfer() != null) { if (ref != null && ref.fieldFunc() != null) {
return null; return null;
} }
if (!(checkMemberType(factory, clazz, method.getGenericReturnType(), method.getReturnType()))) { if (!(checkMemberType(factory, clazz, method.getGenericReturnType(), method.getReturnType()))) {

View File

@@ -4,19 +4,19 @@
package org.redkale.test.convert; package org.redkale.test.convert;
import java.util.function.BiFunction;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.redkale.convert.ConvertColumn; import org.redkale.convert.ConvertColumnHandler;
import org.redkale.convert.ConvertColumnTransfer;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
/** /**
* *
* @author zhangjx * @author zhangjx
*/ */
public class ConvertTransferTest { public class ConvertColumnHandlerTest {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
ConvertTransferTest test = new ConvertTransferTest(); ConvertColumnHandlerTest test = new ConvertColumnHandlerTest();
test.run1(); test.run1();
} }
@@ -32,7 +32,7 @@ public class ConvertTransferTest {
private String name; private String name;
@ConvertColumn(tranfer = ParamTransfer.class) @ConvertColumnHandler(ParamColumnHandler.class)
private String phone; private String phone;
public String getName() { 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 @Override
public Object transfer(Object obj, String field, String value) { public String apply(String field, String value) {
if (value == null || value.length() < 5) { if (value == null || value.length() < 5) {
return value; return value;
} else { } else {