From 19041335b4bd21ff1db6661a9606fe3174fbf6f8 Mon Sep 17 00:00:00 2001 From: redkale Date: Tue, 4 Jun 2024 17:26:15 +0800 Subject: [PATCH] =?UTF-8?q?ConvertColumnHandler=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/redkale/boot/Application.java | 8 +- .../org/redkale/convert/ConvertColumn.java | 9 -- .../redkale/convert/ConvertColumnEntry.java | 24 ++-- .../redkale/convert/ConvertColumnHandler.java | 59 ++++++++++ .../convert/ConvertColumnTransfer.java | 29 ----- .../org/redkale/convert/ConvertFactory.java | 104 +++++++++++------- .../java/org/redkale/convert/EnMember.java | 15 +-- .../org/redkale/convert/ObjectEncoder.java | 8 +- .../redkale/convert/json/JsonDynEncoder.java | 2 +- ...est.java => ConvertColumnHandlerTest.java} | 14 +-- 10 files changed, 163 insertions(+), 109 deletions(-) create mode 100644 src/main/java/org/redkale/convert/ConvertColumnHandler.java delete mode 100644 src/main/java/org/redkale/convert/ConvertColumnTransfer.java rename src/test/java/org/redkale/test/convert/{ConvertTransferTest.java => ConvertColumnHandlerTest.java} (76%) diff --git a/src/main/java/org/redkale/boot/Application.java b/src/main/java/org/redkale/boot/Application.java index 1f200dd3d..f86913926 100644 --- a/src/main/java/org/redkale/boot/Application.java +++ b/src/main/java/org/redkale/boot/Application.java @@ -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 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 diff --git a/src/main/java/org/redkale/convert/ConvertColumn.java b/src/main/java/org/redkale/convert/ConvertColumn.java index a1837e981..50cded9e2 100644 --- a/src/main/java/org/redkale/convert/ConvertColumn.java +++ b/src/main/java/org/redkale/convert/ConvertColumn.java @@ -50,15 +50,6 @@ public @interface ConvertColumn { */ ConvertType type() default ConvertType.ALL; - /** - * 字段值转换器 - * - * @return ConvertColumnTransfer实现类 - * - * @since 2.8.0 - */ - Class tranfer() default ConvertColumnTransfer.class; - /** * ConvertColumn 的多用类 * diff --git a/src/main/java/org/redkale/convert/ConvertColumnEntry.java b/src/main/java/org/redkale/convert/ConvertColumnEntry.java index e73666868..704b73023 100644 --- a/src/main/java/org/redkale/convert/ConvertColumnEntry.java +++ b/src/main/java/org/redkale/convert/ConvertColumnEntry.java @@ -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 fieldFunc; public ConvertColumnEntry() {} - public ConvertColumnEntry(ConvertColumn column, ConvertColumnTransfer transfer) { + public ConvertColumnEntry(ConvertColumn column, BiFunction 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 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 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 fieldFunc() { + return fieldFunc; } public String name() { diff --git a/src/main/java/org/redkale/convert/ConvertColumnHandler.java b/src/main/java/org/redkale/convert/ConvertColumnHandler.java new file mode 100644 index 000000000..9b08582cb --- /dev/null +++ b/src/main/java/org/redkale/convert/ConvertColumnHandler.java @@ -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; + +/** + * 字段值转换器,常见于脱敏操作 + * + *

详情见: 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 value() default BiFunction.class; + + /** + * 解析/序列化定制化的TYPE + * + * @return JSON or BSON or ALL + */ + ConvertType type() default ConvertType.ALL; + + /** + * ConvertColumnHandler 的多用类 + * + *

详情见: https://redkale.org + * + * @author zhangjx + * @since 2.8.0 + */ + @Documented + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + public static @interface ConvertColumnHandlers { + + ConvertColumnHandler[] value(); + } +} diff --git a/src/main/java/org/redkale/convert/ConvertColumnTransfer.java b/src/main/java/org/redkale/convert/ConvertColumnTransfer.java deleted file mode 100644 index c163b16bb..000000000 --- a/src/main/java/org/redkale/convert/ConvertColumnTransfer.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - -*/ - -package org.redkale.convert; - -/** - * 字段值转换器,常见于脱敏操作 - * - *

详情见: https://redkale.org - * - * @author zhangjx - * @since 2.8.0 - * - * @param 字段类型 - */ -public interface ConvertColumnTransfer { - - /** - * 字段值转换 - * - * @param obj 父对象 - * @param field 字段名 - * @param value 字段值 - * - * @return Object - */ - public Object transfer(Object obj, String field, F value); -} diff --git a/src/main/java/org/redkale/convert/ConvertFactory.java b/src/main/java/org/redkale/convert/ConvertFactory.java index ee42e2ff8..2abde5a34 100644 --- a/src/main/java/org/redkale/convert/ConvertFactory.java +++ b/src/main/java/org/redkale/convert/ConvertFactory.java @@ -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 { private final ConcurrentHashMap columnEntrys = new ConcurrentHashMap(); - private final ConcurrentHashMap transfers = new ConcurrentHashMap(); + private final ConcurrentHashMap columnHandlers = new ConcurrentHashMap(); private final Set skipIgnores = new HashSet(); @@ -73,7 +74,7 @@ public abstract class ConvertFactory { private boolean skipAllIgnore = false; - private Consumer transferConsumer; + private Consumer columnHandlerConsumer; protected ConvertFactory(ConvertFactory parent, int features) { this.features = features; @@ -414,8 +415,49 @@ public abstract class ConvertFactory { 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 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 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 { } 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 { 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 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 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 { return entry; } } + if (colHandler != null) { + return new ConvertColumnEntry(fieldName, false, colConvertType, colHandler); + } return null; } @@ -890,11 +918,11 @@ public abstract class ConvertFactory { return child; } - private Consumer findTransferConsumer() { - if (transferConsumer != null) { - return transferConsumer; + private Consumer 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 { } /** - * 设置ConvertColumnTransfer初始化的处理函数 + * 设置ColumnHandler初始化的处理函数 * - * @param consumer ConvertColumnTransfer处理函数 + * @param consumer ColumnHandler处理函数 */ - public final void registerTransferConsumer(Consumer consumer) { - this.transferConsumer = consumer; + public final void registerColumnHandlerConsumer(Consumer consumer) { + this.columnHandlerConsumer = consumer; } /** @@ -1082,12 +1110,12 @@ public abstract class ConvertFactory { return result; } - public final ConvertColumnTransfer findTransfer(Class type) { - ConvertColumnTransfer transfer = transfers.get(type); - if (transfer != null) { - return transfer; + public final BiFunction findColumnHandler(Class 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 { return (Encodeable) anyEncoder; } - public final void register(final Class clazz, final C transfer) { - transfers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(transfer)); + public final void register(Class clazz, C columnHandler) { + columnHandlers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(columnHandler)); } public final void register(final Type clazz, final SimpledCoder coder) { diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java index 25dca1428..5e3d5d304 100644 --- a/src/main/java/org/redkale/convert/EnMember.java +++ b/src/main/java/org/redkale/convert/EnMember.java @@ -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 { final Method method; // 对应类成员的Method也可能为null - final ConvertColumnTransfer transfer; // 一般为null + final BiFunction fieldFunc; // 一般为null int index; @@ -50,16 +51,12 @@ public final class EnMember { int tag; // 主要给protobuf使用 public EnMember( - Attribute attribute, - Encodeable encoder, - Field field, - Method method, - ConvertColumnTransfer transfer) { + Attribute attribute, Encodeable 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 { 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; } diff --git a/src/main/java/org/redkale/convert/ObjectEncoder.java b/src/main/java/org/redkale/convert/ObjectEncoder.java index 4fadcfc7a..7ed18da3d 100644 --- a/src/main/java/org/redkale/convert/ObjectEncoder.java +++ b/src/main/java/org/redkale/convert/ObjectEncoder.java @@ -110,7 +110,7 @@ public class ObjectEncoder implements Encodeable { 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 implements Encodeable { 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 implements Encodeable { 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 implements Encodeable { null, null, null, - ref2 == null ? null : ref2.transfer()); + ref2 == null ? null : ref2.fieldFunc()); if (ref2 != null) { member.index = ref2.getIndex(); } diff --git a/src/main/java/org/redkale/convert/json/JsonDynEncoder.java b/src/main/java/org/redkale/convert/json/JsonDynEncoder.java index cb92a24bb..707eaa0b5 100644 --- a/src/main/java/org/redkale/convert/json/JsonDynEncoder.java +++ b/src/main/java/org/redkale/convert/json/JsonDynEncoder.java @@ -257,7 +257,7 @@ public abstract class JsonDynEncoder implements Encodeable { 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()))) { diff --git a/src/test/java/org/redkale/test/convert/ConvertTransferTest.java b/src/test/java/org/redkale/test/convert/ConvertColumnHandlerTest.java similarity index 76% rename from src/test/java/org/redkale/test/convert/ConvertTransferTest.java rename to src/test/java/org/redkale/test/convert/ConvertColumnHandlerTest.java index 300fed3a4..f8dd463a4 100644 --- a/src/test/java/org/redkale/test/convert/ConvertTransferTest.java +++ b/src/test/java/org/redkale/test/convert/ConvertColumnHandlerTest.java @@ -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 { + public static class ParamColumnHandler implements BiFunction { @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 {