From 62290fb35f295b62c19a13a84b2d0e56c17b3fe5 Mon Sep 17 00:00:00 2001 From: godotg Date: Mon, 1 Jul 2024 17:42:46 +0800 Subject: [PATCH] perf[wrapper]: generic type interface --- .../java/com/zfoo/orm/cache/EntityCache.java | 24 ++--- .../zfoo/orm/cache/wrapper/EnhanceUtils.java | 89 ++++++++++--------- .../zfoo/orm/cache/wrapper/EntityWrapper.java | 14 +-- .../orm/cache/wrapper/IEntityWrapper.java | 8 +- 4 files changed, 66 insertions(+), 69 deletions(-) diff --git a/orm/src/main/java/com/zfoo/orm/cache/EntityCache.java b/orm/src/main/java/com/zfoo/orm/cache/EntityCache.java index 745250ca..32101f1e 100644 --- a/orm/src/main/java/com/zfoo/orm/cache/EntityCache.java +++ b/orm/src/main/java/com/zfoo/orm/cache/EntityCache.java @@ -56,28 +56,21 @@ public class EntityCache, E extends IEntity> imple private final Class clazz; private final EntityDef entityDef; - private final LazyCache> cache; - - private IEntityWrapper wrapper; + private final IEntityWrapper wrapper; - @SuppressWarnings("unchecked") - public EntityCache(Class> entityClass, EntityDef entityDef) { - this.clazz = (Class) entityClass; + public EntityCache(Class entityClass, EntityDef entityDef) { + this.clazz = entityClass; + this.entityDef = entityDef; // 创建CacheVersion - var entityWrapper = new EntityWrapper(entityClass); + var entityWrapper = new EntityWrapper<>(clazz); if (GraalVmUtils.isGraalVM()) { wrapper = entityWrapper; } else { - try { - wrapper = EnhanceUtils.createEntityWrapper(entityWrapper); - } catch (Exception e) { - throw new RuntimeException(e); - } + wrapper = EnhanceUtils.createEntityWrapper(entityWrapper); } - var removeCallback = new BiConsumer>, LazyCache.RemovalCause>() { @Override public void accept(Pair> pair, LazyCache.RemovalCause removalCause) { @@ -114,7 +107,6 @@ public class EntityCache, E extends IEntity> imple } }; var expireCheckIntervalMillis = Math.max(3 * TimeUtils.MILLIS_PER_SECOND, entityDef.getExpireMillisecond() / 10); - this.entityDef = entityDef; this.cache = new LazyCache<>(entityDef.getCacheSize(), entityDef.getExpireMillisecond(), expireCheckIntervalMillis, removeCallback); if (CollectionUtils.isNotEmpty(entityDef.getIndexDefMap())) { @@ -151,7 +143,6 @@ public class EntityCache, E extends IEntity> imple return entity; } - @SuppressWarnings("unchecked") @Override public E loadOrCreate(PK pk) { AssertionUtils.notNull(pk); @@ -164,7 +155,7 @@ public class EntityCache, E extends IEntity> imple // 如果数据库中不存在则给一个默认值 if (entity == null) { - entity = (E) wrapper.newEntity(pk); + entity = wrapper.newEntity(pk); OrmContext.getAccessor().insert(entity); } pnode = new PNode<>(entity); @@ -403,7 +394,6 @@ public class EntityCache, E extends IEntity> imple cache.remove(id); load(id); logger.warn("[database:{}] document of entity [id:{}] version [{}] is greater than cache [vs:{}]", clazz.getSimpleName(), id, dbEntityVersion, entityVersion); - continue; } } diff --git a/orm/src/main/java/com/zfoo/orm/cache/wrapper/EnhanceUtils.java b/orm/src/main/java/com/zfoo/orm/cache/wrapper/EnhanceUtils.java index 94120505..9c5e6a06 100644 --- a/orm/src/main/java/com/zfoo/orm/cache/wrapper/EnhanceUtils.java +++ b/orm/src/main/java/com/zfoo/orm/cache/wrapper/EnhanceUtils.java @@ -16,11 +16,13 @@ import com.zfoo.orm.model.IEntity; import com.zfoo.orm.schema.NamespaceHandler; import com.zfoo.protocol.util.StringUtils; import com.zfoo.protocol.util.UuidUtils; -import javassist.*; +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; import org.bson.types.ObjectId; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -62,52 +64,57 @@ public abstract class EnhanceUtils { } } - public static IEntityWrapper createEntityWrapper(EntityWrapper entityWrapper) throws NotFoundException, CannotCompileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { - var classPool = ClassPool.getDefault(); + @SuppressWarnings("unchecked") + public static , E extends IEntity> IEntityWrapper createEntityWrapper(EntityWrapper entityWrapper) { + try { + var classPool = ClassPool.getDefault(); - Class clazz = entityWrapper.getEntityClass(); - Field idField = entityWrapper.getIdField(); - Method setIdMethod = entityWrapper.getSetIdMethod(); - Field versionField = entityWrapper.getVersionField(); - Method getVersionMethod = entityWrapper.getGetVersionMethod(); - Method setVersionMethod = entityWrapper.getSetVersionMethod(); + Class clazz = entityWrapper.getEntityClass(); + Field idField = entityWrapper.getIdField(); + Method setIdMethod = entityWrapper.getSetIdMethod(); + Field versionField = entityWrapper.getVersionField(); + Method getVersionMethod = entityWrapper.getGetVersionMethod(); + Method setVersionMethod = entityWrapper.getSetVersionMethod(); - // 定义类名称 - CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getName() + StringUtils.capitalize(NamespaceHandler.ORM) + UuidUtils.getLocalIntId()); - enhanceClazz.addInterface(classPool.get(IEntityWrapper.class.getName())); + // 定义类名称 + CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getName() + StringUtils.capitalize(NamespaceHandler.ORM) + UuidUtils.getLocalIntId()); + enhanceClazz.addInterface(classPool.get(IEntityWrapper.class.getName())); - // 定义类实现的接口方法name - CtMethod newEntityMethod = new CtMethod(classPool.get(IEntity.class.getName()), "newEntity", classPool.get(new String[]{Object.class.getName()}), enhanceClazz); - newEntityMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); - String newEntityMethodBody = StringUtils.format("{ {} entity = new {}(); entity.{}({}); return entity; }", clazz.getName(), clazz.getName(), setIdMethod.getName(), rawObjectId(idField)); - newEntityMethod.setBody(newEntityMethodBody); - enhanceClazz.addMethod(newEntityMethod); + // 定义类实现的接口方法name + CtMethod newEntityMethod = new CtMethod(classPool.get(IEntity.class.getName()), "newEntity", classPool.get(new String[]{Comparable.class.getName()}), enhanceClazz); + newEntityMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); + String newEntityMethodBody = StringUtils.format("{ {} entity = new {}(); entity.{}({}); return entity; }", clazz.getName(), clazz.getName(), setIdMethod.getName(), rawObjectId(idField)); + newEntityMethod.setBody(newEntityMethodBody); + enhanceClazz.addMethod(newEntityMethod); - // 定义类实现的接口方法name - CtMethod versionFieldNameMethod = new CtMethod(classPool.get(String.class.getName()), "versionFieldName", null, enhanceClazz); - versionFieldNameMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); - String versionFieldNameMethodBody = versionField == null ? "{ return null; }" : StringUtils.format("{ return \"{}\"; }", entityWrapper.versionFieldName()); - versionFieldNameMethod.setBody(versionFieldNameMethodBody); - enhanceClazz.addMethod(versionFieldNameMethod); + // 定义类实现的接口方法name + CtMethod versionFieldNameMethod = new CtMethod(classPool.get(String.class.getName()), "versionFieldName", null, enhanceClazz); + versionFieldNameMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); + String versionFieldNameMethodBody = versionField == null ? "{ return null; }" : StringUtils.format("{ return \"{}\"; }", entityWrapper.versionFieldName()); + versionFieldNameMethod.setBody(versionFieldNameMethodBody); + enhanceClazz.addMethod(versionFieldNameMethod); - // 定义类实现的接口方法gvs - CtMethod gvsMethod = new CtMethod(classPool.get(long.class.getName()), "gvs", classPool.get(new String[]{IEntity.class.getName()}), enhanceClazz); - gvsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); - String gvsMethodBody = getVersionMethod == null ? "{ return 0L; }" : StringUtils.format("{ return (({})$1).{}(); }", clazz.getName(), getVersionMethod.getName()); - gvsMethod.setBody(gvsMethodBody); - enhanceClazz.addMethod(gvsMethod); + // 定义类实现的接口方法gvs + CtMethod gvsMethod = new CtMethod(classPool.get(long.class.getName()), "gvs", classPool.get(new String[]{IEntity.class.getName()}), enhanceClazz); + gvsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); + String gvsMethodBody = getVersionMethod == null ? "{ return 0L; }" : StringUtils.format("{ return (({})$1).{}(); }", clazz.getName(), getVersionMethod.getName()); + gvsMethod.setBody(gvsMethodBody); + enhanceClazz.addMethod(gvsMethod); - // 定义类实现的接口方法svs - CtMethod svsMethod = new CtMethod(classPool.get(void.class.getName()), "svs", classPool.get(new String[]{IEntity.class.getName(), long.class.getName()}), enhanceClazz); - svsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); - String svsMethodBody = setVersionMethod == null ? "{}" : StringUtils.format("{ (({})$1).{}($2); }", clazz.getName(), setVersionMethod.getName()); - svsMethod.setBody(svsMethodBody); - enhanceClazz.addMethod(svsMethod); + // 定义类实现的接口方法svs + CtMethod svsMethod = new CtMethod(classPool.get(void.class.getName()), "svs", classPool.get(new String[]{IEntity.class.getName(), long.class.getName()}), enhanceClazz); + svsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); + String svsMethodBody = setVersionMethod == null ? "{}" : StringUtils.format("{ (({})$1).{}($2); }", clazz.getName(), setVersionMethod.getName()); + svsMethod.setBody(svsMethodBody); + enhanceClazz.addMethod(svsMethod); - // 释放缓存 - enhanceClazz.detach(); + // 释放缓存 + enhanceClazz.detach(); - Class resultClazz = enhanceClazz.toClass(IEntityWrapper.class); - return (IEntityWrapper) resultClazz.newInstance(); + Class resultClazz = enhanceClazz.toClass(IEntityWrapper.class); + return (IEntityWrapper) resultClazz.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } } } diff --git a/orm/src/main/java/com/zfoo/orm/cache/wrapper/EntityWrapper.java b/orm/src/main/java/com/zfoo/orm/cache/wrapper/EntityWrapper.java index 6e41a509..7693464a 100644 --- a/orm/src/main/java/com/zfoo/orm/cache/wrapper/EntityWrapper.java +++ b/orm/src/main/java/com/zfoo/orm/cache/wrapper/EntityWrapper.java @@ -25,9 +25,9 @@ import java.lang.reflect.Method; /** * @author godotg */ -public class EntityWrapper implements IEntityWrapper { +public class EntityWrapper, E extends IEntity> implements IEntityWrapper { - private Class> entityClass; + private Class entityClass; private Field idField; private Method setIdMethod; // ----------------------------------------------------------------------------------------------------------------- @@ -35,7 +35,7 @@ public class EntityWrapper implements IEntityWrapper { private Method getVersionMethod; private Method setVersionMethod; - public EntityWrapper(Class> entityClass) { + public EntityWrapper(Class entityClass) { this.entityClass = entityClass; var idFields = ReflectionUtils.getFieldsByAnnoInPOJOClass(entityClass, Id.class); @@ -54,7 +54,7 @@ public class EntityWrapper implements IEntityWrapper { } @Override - public IEntity newEntity(Object id) { + public E newEntity(PK id) { var entity = ReflectionUtils.newInstance(entityClass); ReflectionUtils.invokeMethod(entity, setIdMethod, id); return entity; @@ -69,7 +69,7 @@ public class EntityWrapper implements IEntityWrapper { } @Override - public long gvs(IEntity entity) { + public long gvs(E entity) { if (getVersionMethod == null) { return 0; } @@ -77,14 +77,14 @@ public class EntityWrapper implements IEntityWrapper { } @Override - public void svs(IEntity entity, long vs) { + public void svs(E entity, long vs) { if (setVersionMethod == null) { return; } ReflectionUtils.invokeMethod(entity, setVersionMethod, vs); } - public Class> getEntityClass() { + public Class getEntityClass() { return entityClass; } diff --git a/orm/src/main/java/com/zfoo/orm/cache/wrapper/IEntityWrapper.java b/orm/src/main/java/com/zfoo/orm/cache/wrapper/IEntityWrapper.java index 83fffb74..2cbf1203 100644 --- a/orm/src/main/java/com/zfoo/orm/cache/wrapper/IEntityWrapper.java +++ b/orm/src/main/java/com/zfoo/orm/cache/wrapper/IEntityWrapper.java @@ -18,9 +18,9 @@ import com.zfoo.orm.model.IEntity; /** * @author godotg */ -public interface IEntityWrapper { +public interface IEntityWrapper, E extends IEntity> { - IEntity newEntity(Object id); + E newEntity(PK id); /** * version field的名称 @@ -41,8 +41,8 @@ public interface IEntityWrapper { *

* 分布式环境下,要想服务器性能好,就要做成有状态的,有状态就要遇到这种多服对同一条数据写入问题,这是一个千古难以解决的问题,进退两难。 */ - long gvs(IEntity entity); + long gvs(E entity); - void svs(IEntity entity, long vs); + void svs(E entity, long vs); }