Skip to content

Commit

Permalink
use caching in ReflectionMembers to speed up repeated access
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladicek committed Nov 15, 2023
1 parent 43f3077 commit 8df3ad5
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ public InvokerBuilder<InvokerInfo> createInvoker(MethodInfo methodInfo) {
AnnotatedMethod<?> cdiMethod = (AnnotatedMethod<?>) ((MethodInfoImpl) methodInfo).cdiDeclaration;

// verify that the `methodInfo` belongs to this bean
// TODO inefficient when many invokers are created for methods of a single bean
if (!ReflectionMembers.allMethods(cdiBean.getBeanClass()).contains(cdiMethod.getJavaMember())) {
throw new DeploymentException("Method does not belong to bean " + cdiBean.getBeanClass().getName()
+ ": " + methodInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ public void validation(@Priority(Integer.MAX_VALUE) @Observes jakarta.enterprise
enhancementActions.clear();
registrationActions.clear();

ReflectionMembers.clearCaches();

this.bm = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
package org.jboss.weld.lite.extension.translator;

import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;

class ReflectionMembers {

private ReflectionMembers() {
}

static Set<Method> allMethods(Class<?> clazz) {
Set<Method> result = new HashSet<>();
forEachSuperclass(clazz, it -> result.addAll(Arrays.asList(it.getDeclaredMethods())));
return result;
static ConcurrentMap<Class<?>, Set<java.lang.reflect.Method>> cachedMethods = new ConcurrentHashMap<>();
static ConcurrentMap<Class<?>, Set<java.lang.reflect.Field>> cachedFields = new ConcurrentHashMap<>();

static Set<java.lang.reflect.Method> allMethods(Class<?> clazz) {
return cachedMethods.computeIfAbsent(clazz, ignored -> {
Set<java.lang.reflect.Method> result = new HashSet<>();
forEachSuperclass(clazz, it -> result.addAll(Arrays.asList(it.getDeclaredMethods())));
return result;
});
}

static Set<java.lang.reflect.Field> allFields(Class<?> clazz) {
Set<java.lang.reflect.Field> result = new HashSet<>();
forEachSuperclass(clazz, it -> result.addAll(Arrays.asList(it.getDeclaredFields())));
return result;
return cachedFields.computeIfAbsent(clazz, ignored -> {
Set<java.lang.reflect.Field> result = new HashSet<>();
forEachSuperclass(clazz, it -> result.addAll(Arrays.asList(it.getDeclaredFields())));
return result;
});
}

static void clearCaches() {
cachedMethods.clear();
cachedFields.clear();
}

private static void forEachSuperclass(Class<?> clazz, Consumer<Class<?>> action) {
Expand Down

0 comments on commit 8df3ad5

Please sign in to comment.