mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-17 00:26:30 +00:00
perf[storage]: Interface optimization
1.优化storage函数式方法引用缓存,采用spring自带的实现; 2.优化合并属性工具类;
This commit is contained in:
@@ -457,8 +457,8 @@ public class OrmManager implements IOrmManager {
|
||||
|
||||
for (var field : filedList) {
|
||||
// entity必须包含属性的get和set方法
|
||||
ReflectionUtils.fieldToGetMethod(clazz, field);
|
||||
ReflectionUtils.fieldToSetMethod(clazz, field);
|
||||
FieldUtils.fieldToGetMethod(clazz, field);
|
||||
FieldUtils.fieldToSetMethod(clazz, field);
|
||||
|
||||
// 是一个基本类型变量
|
||||
var fieldType = field.getType();
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.enhance.*;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.FieldUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import javassist.*;
|
||||
@@ -198,7 +198,7 @@ public abstract class EnhanceUtils {
|
||||
.writeObject(builder, StringUtils.format("packet.{}", field.getName()), field, fieldRegistration);
|
||||
} else {
|
||||
enhanceSerializer(fieldRegistration.serializer())
|
||||
.writeObject(builder, StringUtils.format("packet.{}()", ReflectionUtils.fieldToGetMethod(packetClazz, field)), field, fieldRegistration);
|
||||
.writeObject(builder, StringUtils.format("packet.{}()", FieldUtils.fieldToGetMethod(packetClazz, field)), field, fieldRegistration);
|
||||
}
|
||||
}
|
||||
builder.append("}");
|
||||
@@ -246,7 +246,7 @@ public abstract class EnhanceUtils {
|
||||
if (Modifier.isPublic(field.getModifiers())) {
|
||||
builder.append(StringUtils.format("packet.{}={};", field.getName(), readObject));
|
||||
} else {
|
||||
builder.append(StringUtils.format("packet.{}({});", ReflectionUtils.fieldToSetMethod(packetClazz, field), readObject));
|
||||
builder.append(StringUtils.format("packet.{}({});", FieldUtils.fieldToSetMethod(packetClazz, field), readObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.zfoo.protocol.util;
|
||||
|
||||
import com.zfoo.protocol.exception.RunException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 属性工具类
|
||||
*
|
||||
* @author veione
|
||||
*/
|
||||
public class FieldUtils {
|
||||
|
||||
public static String fieldToGetMethod(Class<?> clazz, Field field) {
|
||||
var fieldName = field.getName();
|
||||
ReflectionUtils.assertIsStandardFieldName(field);
|
||||
|
||||
var methodName = "get" + StringUtils.capitalize(fieldName);
|
||||
|
||||
if (clazz.isRecord()) {
|
||||
methodName = fieldName;
|
||||
}
|
||||
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
// java的get方法对boolean值有可能对应get或者is,所以尝试获取两种不同的get方法,当两种都获取不到才抛异常
|
||||
}
|
||||
|
||||
// 如果属性名的第一个字母是小写且第二个字母大写,那么该属性名直接用作 getter/setter。例如属性名为uName,对应的方法是getuName/setuName。
|
||||
// 如果属性名以大写字母开头,属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,对应的方法是getName/setName。
|
||||
methodName = "get" + fieldName;
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
|
||||
methodName = "is" + StringUtils.capitalize(fieldName);
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RunException("field:[{}] has no getMethod or isMethod in class:[{}]", field.getName(), clazz.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public static String fieldToSetMethod(Class<?> clazz, Field field) {
|
||||
var fieldName = field.getName();
|
||||
|
||||
ReflectionUtils.assertIsStandardFieldName(field);
|
||||
|
||||
var methodName = "set" + StringUtils.capitalize(fieldName);
|
||||
|
||||
if (clazz.isRecord()) {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName, field.getType());
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
|
||||
methodName = "set" + fieldName;
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName, field.getType());
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RunException("field:[{}] has no setMethod in class:[{}]", field.getName(), clazz.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public static String methodToProperty(String name) {
|
||||
if (name.startsWith("is")) {
|
||||
name = name.substring(2);
|
||||
} else if (name.startsWith("get") || name.startsWith("set")) {
|
||||
name = name.substring(3);
|
||||
}
|
||||
|
||||
if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {
|
||||
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean isProperty(String name) {
|
||||
return isGetter(name) || isSetter(name);
|
||||
}
|
||||
|
||||
public static boolean isGetter(String name) {
|
||||
return name.startsWith("get") && name.length() > 3 || name.startsWith("is") && name.length() > 2;
|
||||
}
|
||||
|
||||
public static boolean isSetter(String name) {
|
||||
return name.startsWith("set") && name.length() > 3;
|
||||
}
|
||||
}
|
||||
@@ -320,67 +320,6 @@ public abstract class ReflectionUtils {
|
||||
.toList();
|
||||
}
|
||||
|
||||
public static String fieldToGetMethod(Class<?> clazz, Field field) {
|
||||
var fieldName = field.getName();
|
||||
assertIsStandardFieldName(field);
|
||||
|
||||
var methodName = "get" + StringUtils.capitalize(fieldName);
|
||||
|
||||
if (clazz.isRecord()) {
|
||||
methodName = fieldName;
|
||||
}
|
||||
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
// java的get方法对boolean值有可能对应get或者is,所以尝试获取两种不同的get方法,当两种都获取不到才抛异常
|
||||
}
|
||||
|
||||
// 如果属性名的第一个字母是小写且第二个字母大写,那么该属性名直接用作 getter/setter。例如属性名为uName,对应的方法是getuName/setuName。
|
||||
// 如果属性名以大写字母开头,属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,对应的方法是getName/setName。
|
||||
methodName = "get" + fieldName;
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
|
||||
methodName = "is" + StringUtils.capitalize(fieldName);
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName);
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RunException("field:[{}] has no getMethod or isMethod in class:[{}]", field.getName(), clazz.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public static String fieldToSetMethod(Class<?> clazz, Field field) {
|
||||
var fieldName = field.getName();
|
||||
|
||||
assertIsStandardFieldName(field);
|
||||
|
||||
var methodName = "set" + StringUtils.capitalize(fieldName);
|
||||
|
||||
if (clazz.isRecord()) {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName, field.getType());
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
|
||||
methodName = "set" + fieldName;
|
||||
try {
|
||||
clazz.getDeclaredMethod(methodName, field.getType());
|
||||
return methodName;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RunException("field:[{}] has no setMethod in class:[{}]", field.getName(), clazz.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Constructor<T> getConstructor(Class<T> clazz) {
|
||||
try {
|
||||
return clazz.getDeclaredConstructor();
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.exception.ExceptionUtils;
|
||||
import com.zfoo.protocol.exception.RunException;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FieldUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.GraalVmUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
@@ -123,7 +124,7 @@ public class StorageManager implements IStorageManager {
|
||||
|
||||
var setMethodName = StringUtils.EMPTY;
|
||||
try {
|
||||
setMethodName = ReflectionUtils.fieldToSetMethod(clazz, field);
|
||||
setMethodName = FieldUtils.fieldToSetMethod(clazz, field);
|
||||
} catch (Exception e) {
|
||||
// 没有setMethod是正确的
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zfoo.storage.util;
|
||||
|
||||
import com.zfoo.protocol.util.FieldUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.storage.util.function.Func1;
|
||||
import com.zfoo.storage.util.support.IdeaProxyLambdaMeta;
|
||||
@@ -7,6 +8,7 @@ import com.zfoo.storage.util.support.LambdaMeta;
|
||||
import com.zfoo.storage.util.support.ReflectLambdaMeta;
|
||||
import com.zfoo.storage.util.support.SerializedLambda;
|
||||
import com.zfoo.storage.util.support.ShadowLambdaMeta;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -15,19 +17,17 @@ import java.lang.reflect.Proxy;
|
||||
/**
|
||||
* @author veione
|
||||
* @version 1.0
|
||||
* @date 2023/9/12
|
||||
*/
|
||||
public final class LambdaUtils {
|
||||
private static final SimpleCache<Class, LambdaMeta> FUNC_CACHE = new SimpleCache<>(64);
|
||||
private static final ConcurrentReferenceHashMap<Class, LambdaMeta> CACHE = new ConcurrentReferenceHashMap<>(64, 0.75F, 16, ConcurrentReferenceHashMap.ReferenceType.WEAK);
|
||||
|
||||
/**
|
||||
* 该缓存可能会在任意不定的时间被清除
|
||||
*
|
||||
* @param func 需要解析的 lambda 对象
|
||||
* @param <T> 类型,被调用的 Function 对象的目标类型
|
||||
* @return 返回解析后的结果
|
||||
*/
|
||||
public static <T> LambdaMeta extract(Serializable func) {
|
||||
public static LambdaMeta extract(Serializable func) {
|
||||
// 1. IDEA 调试模式下 lambda 表达式是一个代理
|
||||
if (func instanceof Proxy) {
|
||||
return new IdeaProxyLambdaMeta((Proxy) func);
|
||||
@@ -75,7 +75,7 @@ public final class LambdaUtils {
|
||||
* @return 字段名称
|
||||
*/
|
||||
public static <T> String getFieldName(Func1<T, ?> func) {
|
||||
return PropertyNamer.methodToProperty(getMethodName(func));
|
||||
return FieldUtils.methodToProperty(getMethodName(func));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public final class LambdaUtils {
|
||||
* @param func 需要解析的 lambda 对象
|
||||
* @return 返回解析后的结果
|
||||
*/
|
||||
private static <T> LambdaMeta _resolve(Serializable func) {
|
||||
return FUNC_CACHE.get(func.getClass(), () -> extract(func));
|
||||
private static LambdaMeta _resolve(Serializable func) {
|
||||
return CACHE.computeIfAbsent(func.getClass(), c -> extract(func));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.zfoo.storage.util;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Copy from ibatis framework.
|
||||
*
|
||||
* @author Clinton Begin
|
||||
*/
|
||||
public final class PropertyNamer {
|
||||
|
||||
private PropertyNamer() {
|
||||
// Prevent Instantiation of Static Class
|
||||
}
|
||||
|
||||
public static String methodToProperty(String name) {
|
||||
if (name.startsWith("is")) {
|
||||
name = name.substring(2);
|
||||
} else if (name.startsWith("get") || name.startsWith("set")) {
|
||||
name = name.substring(3);
|
||||
}
|
||||
|
||||
if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {
|
||||
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean isProperty(String name) {
|
||||
return isGetter(name) || isSetter(name);
|
||||
}
|
||||
|
||||
public static boolean isGetter(String name) {
|
||||
return name.startsWith("get") && name.length() > 3 || name.startsWith("is") && name.length() > 2;
|
||||
}
|
||||
|
||||
public static boolean isSetter(String name) {
|
||||
return name.startsWith("set") && name.length() > 3;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package com.zfoo.storage.util;
|
||||
|
||||
import com.zfoo.storage.util.function.Func0;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 简单缓存,无超时实现,默认使用{@link WeakHashMap}实现缓存自动清理
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @author Looly
|
||||
*/
|
||||
public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 池
|
||||
*/
|
||||
private final Map<K, V> cache;
|
||||
// 乐观读写锁
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
/**
|
||||
* 写的时候每个key一把锁,降低锁的粒度
|
||||
*/
|
||||
protected final Map<K, Lock> keyLockMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 构造,默认使用{@link WeakHashMap}实现缓存自动清理
|
||||
*/
|
||||
public SimpleCache() {
|
||||
this(32);
|
||||
}
|
||||
|
||||
public SimpleCache(int initialCapacity) {
|
||||
this(new WeakHashMap<>(initialCapacity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* <p>
|
||||
* 通过自定义Map初始化,可以自定义缓存实现。<br>
|
||||
* 比如使用{@link WeakHashMap}则会自动清理key,使用HashMap则不会清理<br>
|
||||
* 同时,传入的Map对象也可以自带初始化的键值对,防止在get时创建
|
||||
* </p>
|
||||
*
|
||||
* @param initMap 初始Map,用于定义Map类型
|
||||
*/
|
||||
public SimpleCache(Map<K, V> initMap) {
|
||||
this.cache = initMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存池中查找值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public V get(K key) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
return cache.get(key);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param supplier 如果不存在回调方法,用于生产值对象
|
||||
* @return 值对象
|
||||
*/
|
||||
public V get(K key, Func0<V> supplier) {
|
||||
return get(key, null, supplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param validPredicate 检查结果对象是否可用,如是否断开连接等
|
||||
* @param supplier 如果不存在回调方法或结果不可用,用于生产值对象
|
||||
* @return 值对象
|
||||
*/
|
||||
public V get(K key, Predicate<V> validPredicate, Func0<V> supplier) {
|
||||
V v = get(key);
|
||||
if (null == v && null != supplier) {
|
||||
//每个key单独获取一把锁,降低锁的粒度提高并发能力,see pr#1385@Github
|
||||
final Lock keyLock = keyLockMap.computeIfAbsent(key, k -> new ReentrantLock());
|
||||
keyLock.lock();
|
||||
try {
|
||||
// 双重检查,防止在竞争锁的过程中已经有其它线程写入
|
||||
v = cache.get(key);
|
||||
if (null == v || (null != validPredicate && false == validPredicate.test(v))) {
|
||||
try {
|
||||
v = supplier.call();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
put(key, v);
|
||||
}
|
||||
} finally {
|
||||
keyLock.unlock();
|
||||
keyLockMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 值
|
||||
*/
|
||||
public V put(K key, V value) {
|
||||
// 独占写锁
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
cache.put(key, value);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @return 移除的值
|
||||
*/
|
||||
public V remove(K key) {
|
||||
// 独占写锁
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
return cache.remove(key);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存池
|
||||
*/
|
||||
public void clear() {
|
||||
// 独占写锁
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
this.cache.clear();
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<K, V>> iterator() {
|
||||
return this.cache.entrySet().iterator();
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,21 @@
|
||||
"lambdaCapturingTypes": [
|
||||
{
|
||||
"name": "com.zfoo.storage.util.LambdaUtils"
|
||||
},
|
||||
{
|
||||
"name": "com.zfoo.storage.util.support.SerializedLambda"
|
||||
},
|
||||
{
|
||||
"name": "java.lang.invoke.SerializedLambda"
|
||||
},
|
||||
{
|
||||
"name": "com.zfoo.storage.util.function.Func"
|
||||
},
|
||||
{
|
||||
"name": "com.zfoo.storage.util.function.Func0"
|
||||
},
|
||||
{
|
||||
"name": "com.zfoo.storage.util.function.Func1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
package com.zfoo.storage;
|
||||
|
||||
import com.zfoo.storage.util.PropertyNamer;
|
||||
import com.zfoo.protocol.util.FieldUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -9,20 +9,20 @@ import static org.junit.Assert.assertEquals;
|
||||
* @author veione
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class TestPropertyNamer {
|
||||
public class TestFieldUtils {
|
||||
|
||||
@Test
|
||||
public void testPropertyName() {
|
||||
//前三种主要用于普通的POJO,第四种用于是record类型,方法名就是属性名
|
||||
String getName = PropertyNamer.methodToProperty("getName");
|
||||
String getName = FieldUtils.methodToProperty("getName");
|
||||
assertEquals(getName, "name");
|
||||
String setName = PropertyNamer.methodToProperty("setName");
|
||||
String setName = FieldUtils.methodToProperty("setName");
|
||||
assertEquals(setName, "name");
|
||||
String isName = PropertyNamer.methodToProperty("isName");
|
||||
String isName = FieldUtils.methodToProperty("isName");
|
||||
assertEquals(isName, "name");
|
||||
String name = PropertyNamer.methodToProperty("name");
|
||||
String name = FieldUtils.methodToProperty("name");
|
||||
assertEquals(name, "name");
|
||||
name = PropertyNamer.methodToProperty("Name");
|
||||
name = FieldUtils.methodToProperty("Name");
|
||||
assertEquals(name, "name");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.zfoo.storage;
|
||||
|
||||
import com.zfoo.storage.util.LambdaUtils;
|
||||
import com.zfoo.storage.util.function.Func1;
|
||||
import com.zfoo.storage.util.support.LambdaMeta;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author veione
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class TestLambdaFunction {
|
||||
//https://blog.csdn.net/iteye_19045/article/details/119299015
|
||||
@Test
|
||||
public void testFuncSerialization() throws Exception {
|
||||
Func1<StudentResource, String> func = StudentResource::name;
|
||||
Object object = getObject(func);
|
||||
System.out.println(object);
|
||||
|
||||
Class<? extends Serializable> clazz = func.getClass();
|
||||
Method writeReplace = clazz.getDeclaredMethod("writeReplace");
|
||||
System.out.println(writeReplace);
|
||||
|
||||
LambdaMeta meta = LambdaUtils.extract(func);
|
||||
System.out.println(meta);
|
||||
|
||||
Function<StudentResource, String> func2 = StudentResource::name;
|
||||
Method method = func2.getClass().getDeclaredMethod("writeReplace");
|
||||
object = method.invoke(func2);
|
||||
System.out.println(object);
|
||||
}
|
||||
|
||||
private static Object getObject(Serializable func) throws Exception {
|
||||
Method method = func.getClass().getDeclaredMethod("writeReplace");
|
||||
Object object = method.invoke(func);
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.util.FieldUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.JsonUtils;
|
||||
import com.zfoo.storage.anno.AliasFieldName;
|
||||
@@ -27,7 +28,6 @@ import com.zfoo.storage.manager.StorageInt;
|
||||
import com.zfoo.storage.manager.StorageManager;
|
||||
import com.zfoo.storage.util.ExportUtils;
|
||||
import com.zfoo.storage.util.LambdaUtils;
|
||||
import com.zfoo.storage.util.PropertyNamer;
|
||||
import com.zfoo.storage.util.function.Func1;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.UnpooledHeapByteBuf;
|
||||
@@ -114,7 +114,7 @@ public class ExportBinaryTesting {
|
||||
|
||||
Func1<StudentResource, Integer> ageFunc = StudentResource::age;
|
||||
String methodName = LambdaUtils.extract(ageFunc).getImplMethodName();
|
||||
String fieldName = PropertyNamer.methodToProperty(methodName);
|
||||
String fieldName = FieldUtils.methodToProperty(methodName);
|
||||
System.out.println(methodName);
|
||||
System.out.println(fieldName);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user