From 008e21f8f82e9a278a47dcbcb8ae1f1cf9baa12d Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 8 Oct 2024 20:52:10 +0800 Subject: [PATCH] fix code --- .../hutool/core/io/stream/BOMInputStream.java | 12 +- .../hutool/core/lang/loader/AtomicLoader.java | 5 + .../core/lang/loader/LazyFunLoader.java | 29 +---- .../hutool/core/lang/loader/LazyLoader.java | 5 + .../hutool/core/lang/loader/Loader.java | 23 ++++ .../hutool/core/text/dfa/SensitiveUtil.java | 2 +- .../hutool/core/xml/SAXParserFactoryUtil.java | 15 +-- .../core/lang/loader/LazyFunLoaderTest.java | 14 +- .../hutool/jmh/json/FromJsonStringStrJmh.java | 8 +- .../dromara/hutool/jmh/json/JSONJmhData.java | 43 ++++++ .../dromara/hutool/jmh/json/JsonAddJmh.java | 7 + .../dromara/hutool/jmh/json/JsonPutJmh.java | 7 + .../dromara/hutool/jmh/json/ParseTreeJmh.java | 2 +- .../org/dromara/hutool/json/JSONFactory.java | 14 +- .../hutool/json/engine/HutoolJSONEngine.java | 7 + .../hutool/json/serializer/JSONMapper.java | 40 ++---- .../json/serializer/TypeAdapterManager.java | 122 +++++++----------- .../hutool/json/engine/FastJSONTest.java | 5 +- 18 files changed, 194 insertions(+), 166 deletions(-) create mode 100644 hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JSONJmhData.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/BOMInputStream.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/BOMInputStream.java index 426d02196..94e605b09 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/BOMInputStream.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/stream/BOMInputStream.java @@ -49,7 +49,7 @@ import java.io.PushbackInputStream; public class BOMInputStream extends InputStream { private final PushbackInputStream in; - private boolean isInited = false; + private boolean initialized; private final String defaultCharset; private String charset; @@ -92,7 +92,7 @@ public class BOMInputStream extends InputStream { * @return 编码 */ public String getCharset() { - if (!isInited) { + if (!initialized) { try { init(); } catch (final IOException ex) { @@ -104,13 +104,13 @@ public class BOMInputStream extends InputStream { @Override public void close() throws IOException { - isInited = true; + initialized = true; in.close(); } @Override public int read() throws IOException { - isInited = true; + initialized = true; return in.read(); } @@ -120,7 +120,7 @@ public class BOMInputStream extends InputStream { * @throws IOException 读取引起的异常 */ protected void init() throws IOException { - if (isInited) { + if (initialized) { return; } @@ -146,6 +146,6 @@ public class BOMInputStream extends InputStream { in.unread(bom, (n - unread), unread); } - isInited = true; + initialized = true; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/AtomicLoader.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/AtomicLoader.java index 2e666ff86..7fccb1d25 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/AtomicLoader.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/AtomicLoader.java @@ -57,6 +57,11 @@ public abstract class AtomicLoader implements Loader, Serializable { return result; } + @Override + public boolean isInitialized() { + return null != reference.get(); + } + /** * 初始化被加载的对象
* 如果对象从未被加载过,调用此方法初始化加载对象,此方法只被调用一次 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyFunLoader.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyFunLoader.java index 0bf595c84..6b7f11480 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyFunLoader.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyFunLoader.java @@ -18,7 +18,6 @@ package org.dromara.hutool.core.lang.loader; import org.dromara.hutool.core.lang.Assert; -import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -42,12 +41,13 @@ public class LazyFunLoader extends LazyLoader { /** * 静态工厂方法,提供语义性与编码便利性 + * * @param supplier 用于生成对象的函数 - * @param 对象类型 + * @param 对象类型 * @return 函数式懒加载加载器对象 * @since 5.8.0 */ - public static LazyFunLoader on(final Supplier supplier) { + public static LazyFunLoader of(final Supplier supplier) { Assert.notNull(supplier, "supplier must be not null!"); return new LazyFunLoader<>(supplier); } @@ -68,27 +68,4 @@ public class LazyFunLoader extends LazyLoader { this.supplier = null; return t; } - - /** - * 是否已经初始化 - * - * @return 是/否 - */ - public boolean isInitialize() { - return this.supplier == null; - } - - /** - * 如果已经初始化,就执行传入函数 - * - * @param consumer 待执行函数 - */ - public void ifInitialized(final Consumer consumer) { - Assert.notNull(consumer); - - // 已经初始化 - if (this.isInitialize()) { - consumer.accept(this.get()); - } - } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyLoader.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyLoader.java index 58c900c9b..42ddeb03e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyLoader.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/LazyLoader.java @@ -51,6 +51,11 @@ public abstract class LazyLoader implements Loader, Serializable { return result; } + @Override + public boolean isInitialized() { + return null != object; + } + /** * 初始化被加载的对象
* 如果对象从未被加载过,调用此方法初始化加载对象,此方法只被调用一次 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/Loader.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/Loader.java index 154c32ab1..826d8a61b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/Loader.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/loader/Loader.java @@ -16,6 +16,8 @@ package org.dromara.hutool.core.lang.loader; +import java.util.function.Consumer; + /** * 对象加载抽象接口
* 通过实现此接口自定义实现对象的加载方式,例如懒加载机制、多线程加载等 @@ -34,4 +36,25 @@ public interface Loader { * @return 加载完毕的对象 */ T get(); + + /** + * 是否已经初始化完毕 + * + * @return 是否已经初始化完毕 + */ + default boolean isInitialized() { + return true; + } + + /** + * 如果已经初始化,就执行传入函数 + * + * @param consumer 待执行函数,为{@code null}表示不执行任何操作 + */ + default void ifInitialized(final Consumer consumer) { + // 已经初始化 + if (null != consumer && this.isInitialized()) { + consumer.accept(get()); + } + } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/dfa/SensitiveUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/dfa/SensitiveUtil.java index dbba29903..431e62fbf 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/dfa/SensitiveUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/dfa/SensitiveUtil.java @@ -43,7 +43,7 @@ public final class SensitiveUtil { /** * @return 是否已经被初始化 */ - public static boolean isInited() { + public static boolean isInitialized() { return !sensitiveTree.isEmpty(); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/xml/SAXParserFactoryUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/xml/SAXParserFactoryUtil.java index 3b8951385..fcf26acdf 100755 --- a/hutool-core/src/main/java/org/dromara/hutool/core/xml/SAXParserFactoryUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/xml/SAXParserFactoryUtil.java @@ -16,6 +16,9 @@ package org.dromara.hutool.core.xml; +import org.dromara.hutool.core.lang.loader.LazyFunLoader; +import org.dromara.hutool.core.lang.loader.Loader; + import javax.xml.parsers.SAXParserFactory; /** @@ -29,7 +32,7 @@ public class SAXParserFactoryUtil { /** * Sax读取器工厂缓存 */ - private static volatile SAXParserFactory factory; + private static final Loader factoryLoader = LazyFunLoader.of(()->createFactory(false, true)); /** * 获取全局{@link SAXParserFactory}
@@ -41,15 +44,7 @@ public class SAXParserFactoryUtil { * @return {@link SAXParserFactory} */ public static SAXParserFactory getFactory() { - if (null == factory) { - synchronized (SAXParserFactoryUtil.class) { - if (null == factory) { - factory = createFactory(false, true); - } - } - } - - return factory; + return factoryLoader.get(); } /** diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/lang/loader/LazyFunLoaderTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/lang/loader/LazyFunLoaderTest.java index e52aa1383..3da3b6f1a 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/lang/loader/LazyFunLoaderTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/lang/loader/LazyFunLoaderTest.java @@ -36,7 +36,7 @@ public class LazyFunLoaderTest { final LazyFunLoader loader = new LazyFunLoader<>(BigObject::new); Assertions.assertNotNull(loader.get()); - Assertions.assertTrue(loader.isInitialize()); + Assertions.assertTrue(loader.isInitialized()); // 对于某些对象,在程序关闭时,需要进行销毁操作 loader.ifInitialized(BigObject::destroy); @@ -56,16 +56,16 @@ public class LazyFunLoaderTest { it.destroy(); }); - Assertions.assertFalse(loader.isInitialize()); + Assertions.assertFalse(loader.isInitialized()); } @Test - public void testOnLoadStaticFactoryMethod1() { + public void testOfLoadStaticFactoryMethod1() { - final LazyFunLoader loader = LazyFunLoader.on(BigObject::new); + final LazyFunLoader loader = LazyFunLoader.of(BigObject::new); Assertions.assertNotNull(loader.get()); - Assertions.assertTrue(loader.isInitialize()); + Assertions.assertTrue(loader.isInitialized()); // 对于某些对象,在程序关闭时,需要进行销毁操作 loader.ifInitialized(BigObject::destroy); @@ -74,9 +74,9 @@ public class LazyFunLoaderTest { } @Test - public void testOnLoadStaticFactoryMethod2() { + public void testOfLoadStaticFactoryMethod2() { - final LazyFunLoader loader = LazyFunLoader.on(BigObject::new); + final LazyFunLoader loader = LazyFunLoader.of(BigObject::new); // 若从未使用,则可以避免不必要的初始化 loader.ifInitialized(it -> { diff --git a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/FromJsonStringStrJmh.java b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/FromJsonStringStrJmh.java index e78e331bb..784a2c4e6 100644 --- a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/FromJsonStringStrJmh.java +++ b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/FromJsonStringStrJmh.java @@ -19,6 +19,7 @@ package org.dromara.hutool.jmh.json; import com.fasterxml.jackson.databind.JsonNode; import com.google.gson.JsonElement; import org.dromara.hutool.json.JSON; +import org.dromara.hutool.json.JSONUtil; import org.dromara.hutool.json.engine.JSONEngine; import org.dromara.hutool.json.engine.JSONEngineFactory; import org.openjdk.jmh.annotations.*; @@ -43,7 +44,7 @@ public class FromJsonStringStrJmh { @Setup public void setup() { - jsonStr = "{\"name\":\"张三\",\"age\":18,\"birthday\":\"2020-01-01\"}"; + jsonStr = JSONJmhData.jsonStr; jacksonEngine = JSONEngineFactory.createEngine("jackson"); gsonEngine = JSONEngineFactory.createEngine("gson"); @@ -70,4 +71,9 @@ public class FromJsonStringStrJmh { public void hutoolJSONJmh() { hutoolEngine.fromJsonString(jsonStr, JSON.class); } + + @Benchmark + public void hutoolJSONParseJmh() { + JSONUtil.parseObj(jsonStr); + } } diff --git a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JSONJmhData.java b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JSONJmhData.java new file mode 100644 index 000000000..ceb4a5f7a --- /dev/null +++ b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JSONJmhData.java @@ -0,0 +1,43 @@ +package org.dromara.hutool.jmh.json; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +public class JSONJmhData { + public static String jsonStr = "{\n" + + " \"name\": \"张三\",\n" + + " \"age\": 18,\n" + + " \"birthday\": \"2020-01-01\",\n" + + " \"booleanValue\": true,\n" + + " \"jsonObjectSub\": {\n" + + " \"subStr\": \"abc\",\n" + + " \"subNumber\": 150343445454,\n" + + " \"subBoolean\": true\n" + + " },\n" + + " \"jsonArraySub\": [\n" + + " \"abc\",\n" + + " 123,\n" + + " false\n" + + " ]\n" + + "}"; + + @Data + public static class TestBean{ + private String name; + private int age; + private boolean gender; + private Date createDate; + private Object nullObj; + private SubBean jsonObjectSub; + private List jsonArraySub; + } + + @Data + public static class SubBean{ + private String subStr; + private Long subNumber; + private boolean subBoolean; + } +} diff --git a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonAddJmh.java b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonAddJmh.java index 2fb74f146..39ac498ad 100644 --- a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonAddJmh.java +++ b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonAddJmh.java @@ -29,6 +29,7 @@ public class JsonAddJmh { private JsonArray gson; private com.alibaba.fastjson2.JSONArray fastJSON; private ArrayNode jackson; + private ArrayList arrayList; @Setup @@ -43,6 +44,7 @@ public class JsonAddJmh { gson = new JsonArray(); fastJSON = new com.alibaba.fastjson2.JSONArray(); jackson = JsonNodeFactory.instance.arrayNode(); + arrayList = new ArrayList<>(); Console.log("数据完毕"); } @@ -67,4 +69,9 @@ public class JsonAddJmh { public void jacksonJmh(){ testData.forEach(jackson::add); } + + @Benchmark + public void arrayListJmh(){ + testData.forEach(arrayList::add); + } } diff --git a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonPutJmh.java b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonPutJmh.java index 1f95dbd7c..2710b71f3 100644 --- a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonPutJmh.java +++ b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/JsonPutJmh.java @@ -28,6 +28,7 @@ public class JsonPutJmh { private JsonObject gson; private com.alibaba.fastjson2.JSONObject fastJSON; private ObjectNode jackson; + private HashMap hashMap; @Setup @@ -41,6 +42,7 @@ public class JsonPutJmh { gson = new JsonObject(); fastJSON = new com.alibaba.fastjson2.JSONObject(); jackson = JsonNodeFactory.instance.objectNode(); + hashMap = new HashMap<>(); } @Benchmark @@ -63,4 +65,9 @@ public class JsonPutJmh { public void jacksonJmh(){ testData.forEach(jackson::put); } + + @Benchmark + public void hashMapJmh(){ + testData.forEach(hashMap::put); + } } diff --git a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/ParseTreeJmh.java b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/ParseTreeJmh.java index ea39f009b..e95286514 100644 --- a/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/ParseTreeJmh.java +++ b/hutool-jmh/src/test/java/org/dromara/hutool/jmh/json/ParseTreeJmh.java @@ -32,7 +32,7 @@ public class ParseTreeJmh { @Setup public void setup() { - jsonStr = "{\"name\":\"张三\",\"age\":18,\"birthday\":\"2020-01-01\"}"; + jsonStr = JSONJmhData.jsonStr; } @Benchmark diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONFactory.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONFactory.java index 8aa3c9c12..f8c47cc17 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONFactory.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONFactory.java @@ -17,6 +17,8 @@ package org.dromara.hutool.json; import org.dromara.hutool.core.bean.path.BeanPath; +import org.dromara.hutool.core.lang.loader.LazyFunLoader; +import org.dromara.hutool.core.lang.loader.Loader; import org.dromara.hutool.core.lang.mutable.MutableEntry; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.json.reader.JSONParser; @@ -85,7 +87,7 @@ public class JSONFactory { * entry中,key在JSONObject中为name,在JSONArray中为index */ private final Predicate> predicate; - private volatile JSONMapper mapper; + private final Loader mapperLoader; /** * 构造 @@ -96,6 +98,7 @@ public class JSONFactory { public JSONFactory(final JSONConfig config, final Predicate> predicate) { this.config = ObjUtil.defaultIfNull(config, JSONConfig::of); this.predicate = predicate; + this.mapperLoader = LazyFunLoader.of(()->JSONMapper.of(this)); } /** @@ -146,14 +149,7 @@ public class JSONFactory { * @return {@link JSONMapper} */ public JSONMapper getMapper() { - if (null == this.mapper) { - synchronized (this) { - if (null == this.mapper) { - this.mapper = JSONMapper.of(this); - } - } - } - return this.mapper; + return this.mapperLoader.get(); } /** diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java b/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java index b9def36f0..1fe88006b 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/engine/HutoolJSONEngine.java @@ -59,6 +59,13 @@ public class HutoolJSONEngine extends AbstractJSONEngine { return json.toBean((Type) type); } + @Override + public T fromJsonString(final String jsonStr, final Object type) { + initEngine(); + final JSON json = jsonFactory.parse(jsonStr); + return json.toBean((Type) type); + } + @Override protected void reset() { jsonFactory = null; diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java index abe0ee167..7291128dc 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java @@ -16,7 +16,10 @@ package org.dromara.hutool.json.serializer; +import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Opt; +import org.dromara.hutool.core.lang.loader.LazyFunLoader; +import org.dromara.hutool.core.lang.loader.Loader; import org.dromara.hutool.core.reflect.TypeReference; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.json.*; @@ -55,7 +58,7 @@ public class JSONMapper implements Serializable { } private final JSONFactory factory; - private volatile TypeAdapterManager typeAdapterManager; + private Loader typeAdapterManagerLoader; /** * 构造 @@ -64,6 +67,7 @@ public class JSONMapper implements Serializable { */ public JSONMapper(final JSONFactory factory) { this.factory = factory; + this.typeAdapterManagerLoader = LazyFunLoader.of(TypeAdapterManager::of); } // region ----- typeAdapterManager @@ -74,17 +78,17 @@ public class JSONMapper implements Serializable { * @return 类型转换器管理器 */ public TypeAdapterManager getTypeAdapterManager() { - return this.typeAdapterManager; + return typeAdapterManagerLoader.get(); } /** * 设置自定义类型转换器,用于将自定义类型转换为JSONObject * - * @param typeAdapterManager 类型转换器管理器 + * @param typeAdapterManager 类型转换器管理器,不能为空 * @return this */ public JSONMapper setTypeAdapterManager(final TypeAdapterManager typeAdapterManager) { - this.typeAdapterManager = typeAdapterManager; + this.typeAdapterManagerLoader = () -> Assert.notNull(typeAdapterManager); return this; } @@ -96,7 +100,7 @@ public class JSONMapper implements Serializable { * @return this */ public JSONMapper register(final Type type, final TypeAdapter typeAdapter) { - initTypeAdapterManager().register(type, typeAdapter); + getTypeAdapterManager().register(type, typeAdapter); return this; } @@ -109,7 +113,7 @@ public class JSONMapper implements Serializable { * @return this */ public JSONMapper register(final TypeAdapter typeAdapter) { - initTypeAdapterManager().register(typeAdapter); + getTypeAdapterManager().register(typeAdapter); return this; } //endregion @@ -285,22 +289,6 @@ public class JSONMapper implements Serializable { json.getClass().getName(), result.getClass().getName()); } - /** - * 初始化类型转换器管理器,如果尚未初始化,则初始化,否则直接返回 - * - * @return {@link TypeAdapterManager} - */ - private TypeAdapterManager initTypeAdapterManager() { - if (null == this.typeAdapterManager) { - synchronized (this) { - if (null == this.typeAdapterManager) { - this.typeAdapterManager = TypeAdapterManager.of(); - } - } - } - return this.typeAdapterManager; - } - /** * 获取JSON对象对应的序列化器,先查找局部自定义,如果没有则查找全局自定义 * @@ -311,8 +299,8 @@ public class JSONMapper implements Serializable { private JSONSerializer getSerializer(final Object obj, final Class clazz) { JSONSerializer serializer = null; // 自定义序列化 - if (null != this.typeAdapterManager) { - serializer = this.typeAdapterManager.getSerializer(obj, clazz); + if (this.typeAdapterManagerLoader.isInitialized()) { + serializer = getTypeAdapterManager().getSerializer(obj, clazz); } // 全局自定义序列化 if (null == serializer) { @@ -331,8 +319,8 @@ public class JSONMapper implements Serializable { private JSONDeserializer getDeserializer(final JSON json, final Type type) { JSONDeserializer deserializer = null; // 自定义反序列化 - if (null != this.typeAdapterManager) { - deserializer = this.typeAdapterManager.getDeserializer(json, type); + if (this.typeAdapterManagerLoader.isInitialized()) { + deserializer = getTypeAdapterManager().getDeserializer(json, type); } // 全局自定义反序列化 if (null == deserializer) { diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java index 7b19a4f69..b52f1dc26 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java @@ -16,12 +16,12 @@ package org.dromara.hutool.json.serializer; -import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.lang.Assert; +import org.dromara.hutool.core.lang.loader.LazyFunLoader; +import org.dromara.hutool.core.lang.loader.Loader; import org.dromara.hutool.core.lang.tuple.Pair; import org.dromara.hutool.core.lang.tuple.Triple; import org.dromara.hutool.core.lang.tuple.Tuple; -import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.json.JSON; @@ -83,26 +83,30 @@ public class TypeAdapterManager { /** * 用户自定义序列化器,存储自定义匹配规则的一类对象的转换器 */ - private volatile Set> serializerSet; + private final Loader>> serializerSetLoader; /** * 用户自定义精确类型转换器
* 主要存储类型明确(无子类)的转换器 */ - private volatile Map> serializerMap; + private final Loader>> serializerMapLoader; /** * 用户自定义类型转换器,存储自定义匹配规则的一类对象的转换器 */ - private volatile Set> deserializerSet; + private final Loader>> deserializerSetLoader; /** * 用户自定义精确类型转换器
* 主要存储类型明确(无子类)的转换器 */ - private volatile Map> deserializerMap; + private final Loader>> deserializerMapLoader; /** * 构造 */ public TypeAdapterManager() { + serializerSetLoader = LazyFunLoader.of(LinkedHashSet::new); + serializerMapLoader = LazyFunLoader.of(HashMap::new); + deserializerSetLoader = LazyFunLoader.of(LinkedHashSet::new); + deserializerMapLoader = LazyFunLoader.of(HashMap::new); } // region ----- register @@ -117,12 +121,12 @@ public class TypeAdapterManager { */ public TypeAdapterManager register(final TypeAdapter typeAdapter) { Assert.notNull(typeAdapter, "typeAdapter must be not null!"); - if(typeAdapter instanceof MatcherJSONSerializer || typeAdapter instanceof MatcherJSONDeserializer){ - if(typeAdapter instanceof MatcherJSONSerializer){ - getSerializerSet().add((MatcherJSONSerializer) typeAdapter); + if (typeAdapter instanceof MatcherJSONSerializer || typeAdapter instanceof MatcherJSONDeserializer) { + if (typeAdapter instanceof MatcherJSONSerializer) { + serializerSetLoader.get().add((MatcherJSONSerializer) typeAdapter); } - if(typeAdapter instanceof MatcherJSONDeserializer){ - getDeserializerSet().add((MatcherJSONDeserializer) typeAdapter); + if (typeAdapter instanceof MatcherJSONDeserializer) { + deserializerSetLoader.get().add((MatcherJSONDeserializer) typeAdapter); } return this; } @@ -133,18 +137,18 @@ public class TypeAdapterManager { /** * 注册自定义类型适配器,用于自定义对象序列化和反序列化 * - * @param type 类型 + * @param type 类型 * @param typeAdapter 自定义序列化器,{@code null}表示移除 * @return this */ public TypeAdapterManager register(final Type type, final TypeAdapter typeAdapter) { Assert.notNull(type); - if(typeAdapter instanceof JSONSerializer || typeAdapter instanceof JSONDeserializer){ - if(typeAdapter instanceof JSONSerializer){ - getSerializerMap().put(type, (JSONSerializer) typeAdapter); + if (typeAdapter instanceof JSONSerializer || typeAdapter instanceof JSONDeserializer) { + if (typeAdapter instanceof JSONSerializer) { + serializerMapLoader.get().put(type, (JSONSerializer) typeAdapter); } - if(typeAdapter instanceof JSONDeserializer){ - getDeserializerMap().put(type, (JSONDeserializer) typeAdapter); + if (typeAdapter instanceof JSONDeserializer) { + deserializerMapLoader.get().put(type, (JSONDeserializer) typeAdapter); } return this; } @@ -172,16 +176,19 @@ public class TypeAdapterManager { return (JSONSerializer) ConstructorUtil.newInstanceIfPossible(rawType); } - if (MapUtil.isNotEmpty(this.serializerMap)) { - final JSONSerializer result = this.serializerMap.get(rawType); - if(null != result){ - return (JSONSerializer) result; + if (this.serializerMapLoader.isInitialized()) { + final Map> serializerMap = this.serializerMapLoader.get(); + if (!serializerMap.isEmpty()) { + final JSONSerializer result = serializerMap.get(rawType); + if (null != result) { + return (JSONSerializer) result; + } } } // Matcher - if (CollUtil.isNotEmpty(this.serializerSet)) { - for (final MatcherJSONSerializer serializer : this.serializerSet) { + if (this.serializerSetLoader.isInitialized()) { + for (final MatcherJSONSerializer serializer : this.serializerSetLoader.get()) { if (serializer.match(bean, null)) { return (MatcherJSONSerializer) serializer; } @@ -209,19 +216,24 @@ public class TypeAdapterManager { return (JSONDeserializer) ConstructorUtil.newInstanceIfPossible(rawType); } - if (MapUtil.isNotEmpty(this.deserializerMap)) { - final JSONDeserializer jsonDeserializer = this.deserializerMap.get(rawType); - if (null != jsonDeserializer) { - return (JSONDeserializer) jsonDeserializer; + if (this.deserializerMapLoader.isInitialized()) { + final Map> deserializerMap = this.deserializerMapLoader.get(); + if (!deserializerMap.isEmpty()) { + final JSONDeserializer result = deserializerMap.get(rawType); + if (null != result) { + return (JSONDeserializer) result; + } } } // Matcher - if (CollUtil.isNotEmpty(this.deserializerSet)) { - for (final MatcherJSONDeserializer deserializer : this.deserializerSet) { - if (deserializer.match(json, type)) { - return (JSONDeserializer) deserializer; - } + if (this.deserializerSetLoader.isInitialized()) { + final Set> deserializerSet = this.deserializerSetLoader.get(); + if (!deserializerSet.isEmpty()) { + return (JSONDeserializer) deserializerSet.stream() + .filter(deserializer -> deserializer.match(json, type)) + .findFirst() + .orElse(null); } } @@ -230,52 +242,6 @@ public class TypeAdapterManager { } // endregion - // region ----- getSet or Map - private Set> getSerializerSet() { - if (null == this.serializerSet) { - synchronized (this) { - if (null == this.serializerSet) { - this.serializerSet = new LinkedHashSet<>(); - } - } - } - return this.serializerSet; - } - - private Map> getSerializerMap() { - if (null == this.serializerMap) { - synchronized (this) { - if (null == this.serializerMap) { - this.serializerMap = new HashMap<>(); - } - } - } - return this.serializerMap; - } - - private Set> getDeserializerSet() { - if (null == this.deserializerSet) { - synchronized (this) { - if (null == this.deserializerSet) { - this.deserializerSet = new LinkedHashSet<>(); - } - } - } - return this.deserializerSet; - } - - private Map> getDeserializerMap() { - if (null == this.deserializerMap) { - synchronized (this) { - if (null == this.deserializerMap) { - this.deserializerMap = new HashMap<>(); - } - } - } - return this.deserializerMap; - } - // endregion - /** * 注册默认的序列化器和反序列化器 * diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/engine/FastJSONTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/engine/FastJSONTest.java index 45295c5c9..0c24d9dda 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/engine/FastJSONTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/engine/FastJSONTest.java @@ -20,8 +20,10 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.writer.ObjectWriter; +import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.text.StrUtil; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class FastJSONTest { @@ -42,6 +44,7 @@ public class FastJSONTest { } @Test + @Disabled void toStringTest() { final String jsonStr = "{\"name\":\"张三\",\"age\":18,\"birthday\":\"2020-01-01\"}"; final JSONObject jsonObject = JSON.parseObject(jsonStr); @@ -51,7 +54,7 @@ public class FastJSONTest { final JSONWriter.Context context = writer.getContext(); final ObjectWriter objectWriter = context.getObjectWriter(jsonObject.getClass()); - //Console.log(objectWriter.getClass()); + Console.log(objectWriter.getClass()); writer.close(); }