Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion changes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -euo pipefail
# PR 场景按目标分支对比,避免 CI 修复类提交只修改 .github 时退化为全仓库测试;
# push 场景保持原有 HEAD~1..HEAD 行为,兼容发布工作流。
if [ -n "${GITHUB_BASE_REF:-}" ]; then
git fetch origin "${GITHUB_BASE_REF}" --depth=1 >/dev/null 2>&1 || true
git fetch origin "${GITHUB_BASE_REF}" >/dev/null 2>&1 || true
if git rev-parse --verify "origin/${GITHUB_BASE_REF}" >/dev/null 2>&1; then
diff_args=("origin/${GITHUB_BASE_REF}...HEAD")
else
Expand Down
37 changes: 36 additions & 1 deletion hsweb-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@
<name>${project.artifactId}</name>
<description>核心包</description>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
</path>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.37</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>

<dependency>
Expand Down Expand Up @@ -168,11 +191,23 @@
<artifactId>hsweb-easy-orm-core</artifactId>
</dependency>

<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>9.8</version>
</dependency>

<dependency>
<groupId>io.micrometer</groupId>
<artifactId>context-propagation</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.37</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.hswebframework.web.bean;

import org.hswebframework.ezorm.core.Extendable;
import org.hswebframework.web.bean.accessor.AsmBeanAccessor;

import java.util.Map;

final class AsmAccessorFastBeanCopierBackend extends AccessorFastBeanCopierBackend {
private final AsmBeanAccessor asmBeanAccessor;

AsmAccessorFastBeanCopierBackend() {
this(new AsmBeanAccessor());
}

private AsmAccessorFastBeanCopierBackend(AsmBeanAccessor accessor) {
super(accessor);
this.asmBeanAccessor = accessor;
}

@Override
public Copier createCopier(Class<?> source, Class<?> target) {
if (!Map.class.isAssignableFrom(source)
&& !Map.class.isAssignableFrom(target)
&& !Extendable.class.isAssignableFrom(source)
&& !Extendable.class.isAssignableFrom(target)) {
Copier copier = asmBeanAccessor.createDirectCopier(source, target);
if (copier != null) {
return copier;
}
}
return super.createCopier(source, target);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class ClassDescription {
private final Class<?> type;

private final boolean collectionType;
private final boolean mapType;
private final boolean arrayType;
private final boolean enumType;
private final boolean enumDict;
Expand All @@ -23,24 +24,21 @@ public class ClassDescription {

public ClassDescription(Class<?> type) {
this.type = type;

collectionType = Collection.class.isAssignableFrom(type);
enumDict = EnumDict.class.isAssignableFrom(type);
arrayType = type.isArray();
enumType = type.isEnum();

number = Number.class.isAssignableFrom(type);
this.collectionType = Collection.class.isAssignableFrom(type);
this.mapType = Map.class.isAssignableFrom(type);
this.enumDict = EnumDict.class.isAssignableFrom(type);
this.arrayType = type.isArray();
this.enumType = type.isEnum();
this.number = Number.class.isAssignableFrom(type);
if (enumType) {
enums = type.getEnumConstants();
this.enums = type.getEnumConstants();
} else {
enums = null;
this.enums = null;
}
Map<String, Field> f = new HashMap<>();
ReflectionUtils.doWithFields(type, field -> {
f.put(field.getName(), field);
});
fields = Collections.unmodifiableMap(f);
fieldSize = fields.size();
Map<String, Field> fields = new HashMap<>();
ReflectionUtils.doWithFields(type, field -> fields.put(field.getName(), field));
this.fields = Collections.unmodifiableMap(fields);
this.fieldSize = this.fields.size();
}

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package org.hswebframework.web.bean;


import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ClassDescriptions {

private static final Map<Class<?>, ClassDescription> CACHE = new ConcurrentHashMap<>();
private static final ClassLoaderScopedClassCache<ClassDescription> CACHE = new ClassLoaderScopedClassCache<>();

public static ClassDescription getDescription(Class<?> type) {
return CACHE.computeIfAbsent(type, ClassDescription::new);
}

static void clearCache() {
CACHE.clear();
}

static void clearCache(ClassLoader loader) {
CACHE.clear(loader);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.hswebframework.web.bean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

/**
* 按 classloader 分段的 Class 维度强缓存。
* <p>
* 普通稳定 classloader 直接走强缓存,动态 classloader 场景也保持强缓存命中,
* 通过 {@link #clear(ClassLoader)} 显式回收对应分段,避免弱/软引用在热路径上导致缓存重建。
*
* @param <V> value type
* @author zhouhao
* @since 5.0.2
*/
final class ClassLoaderScopedClassCache<V> {

private final Map<Class<?>, V> stableCache = new ConcurrentHashMap<>();
private final Map<ClassLoader, Map<Class<?>, V>> volatileCache = new ConcurrentHashMap<>();

V computeIfAbsent(Class<?> type, Function<Class<?>, V> mappingFunction) {
if (!FastBeanCopierSupport.isVolatileClassLoaderType(type)) {
return stableCache.computeIfAbsent(type, mappingFunction);
}
ClassLoader loader = FastBeanCopierSupport.getClassLoader(type);
return volatileCache
.computeIfAbsent(loader, ignore -> new ConcurrentHashMap<>())
.computeIfAbsent(type, mappingFunction);
}

void clear() {
stableCache.clear();
volatileCache.clear();
}

void clear(ClassLoader loader) {
if (loader == null) {
clear();
return;
}
stableCache.keySet().removeIf(type -> FastBeanCopierSupport.isClassLoaderMatch(type, loader));
volatileCache.remove(loader);
}
}
Loading
Loading