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.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

View File

@@ -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 的多用类
*

View File

@@ -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() {

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.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) {

View File

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

View File

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

View File

@@ -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()))) {

View File

@@ -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 {