Repository: bval Updated Branches: refs/heads/master ca0104bd4 -> 0e7541f30
BVAL-170 ensure we don't go through class model for each call, cache Proxies.classFor result Project: http://git-wip-us.apache.org/repos/asf/bval/repo Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/0e7541f3 Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/0e7541f3 Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/0e7541f3 Branch: refs/heads/master Commit: 0e7541f30bd49b8d146929fbea2163da914ab656 Parents: ca0104b Author: Romain Manni-Bucau <[email protected]> Authored: Thu Feb 7 10:24:49 2019 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Thu Feb 7 10:24:49 2019 +0100 ---------------------------------------------------------------------- .../org/apache/bval/cdi/BValInterceptor.java | 24 +++++++++++++++++--- .../apache/bval/jsr/ApacheValidatorFactory.java | 6 +++++ .../org/apache/bval/jsr/job/ValidationJob.java | 11 ++++++--- .../java/org/apache/bval/jsr/util/Proxies.java | 4 ++-- 4 files changed, 37 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/bval/blob/0e7541f3/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java b/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java index 042fa7e..6a5a59c 100644 --- a/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java +++ b/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.function.BiPredicate; import javax.annotation.Priority; @@ -96,6 +97,7 @@ public class BValInterceptor implements Serializable { private BValExtension globalConfiguration; private transient volatile ExecutableValidator executableValidator; + private transient volatile ConcurrentMap<Class<?>, Class<?>> classMapping; @SuppressWarnings({ "unchecked", "rawtypes" }) @AroundConstruct // TODO: see previous one @@ -134,7 +136,7 @@ public class BValInterceptor implements Serializable { @AroundInvoke public Object invoke(final InvocationContext context) throws Exception { final Method method = context.getMethod(); - final Class<?> targetClass = Proxies.classFor(context.getTarget().getClass()); + final Class<?> targetClass = getTargetClass(context); if (!isExecutableValidated(targetClass, method, this::computeIsMethodValidated)) { return context.proceed(); @@ -167,8 +169,24 @@ public class BValInterceptor implements Serializable { return result; } - private <T> boolean isConstructorValidated(final Constructor<T> constructor) - { + private Class<?> getTargetClass(final InvocationContext context) { + final Class<?> key = context.getTarget().getClass(); + if (classMapping == null) { + synchronized (this) { + if (classMapping == null) { + classMapping = new ConcurrentHashMap<>(); + } + } + } + Class<?> mapped = classMapping.get(key); + if (mapped == null) { + mapped = Proxies.classFor(key); + classMapping.putIfAbsent(key, mapped); + } + return mapped; + } + + private <T> boolean isConstructorValidated(final Constructor<T> constructor) { return isExecutableValidated(constructor.getDeclaringClass(), constructor, this::computeIsConstructorValidated); } http://git-wip-us.apache.org/repos/asf/bval/blob/0e7541f3/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java index 283d77e..1d7a625 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import javax.validation.ClockProvider; @@ -100,6 +101,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { private final DescriptorManager descriptorManager = new DescriptorManager(this); private final MetadataBuilders metadataBuilders = new MetadataBuilders(); private final ConstraintCached constraintsCache = new ConstraintCached(); + private final Map<Class<?>, Class<?>> unwrappedClassCache = new ConcurrentHashMap<>(); private final Collection<Closeable> toClose = new ArrayList<>(); private final GroupsComputer groupsComputer = new GroupsComputer(); private final ParticipantFactory participantFactory; @@ -137,6 +139,10 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { loadAndVerifyUserCustomizations(configuration); } + public Map<Class<?>, Class<?>> getUnwrappedClassCache() { + return unwrappedClassCache; + } + /** * Get the property map of this {@link ApacheValidatorFactory}. * http://git-wip-us.apache.org/repos/asf/bval/blob/0e7541f3/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java index 8d63c09..3dc2bc4 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java @@ -38,7 +38,6 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; import javax.validation.ConstraintViolation; import javax.validation.ElementKind; import javax.validation.MessageInterpolator; @@ -577,8 +576,14 @@ public abstract class ValidationJob<T> { @SuppressWarnings("unchecked") private <O> BeanD<O> getBeanDescriptor(Object bean) { - final Class<? extends Object> t = Proxies.classFor(Validate.notNull(bean, "bean").getClass()); - return (BeanD<O>) validatorContext.getDescriptorManager().getBeanDescriptor(t); + final Class<?> beanClass = Validate.notNull(bean, "bean").getClass(); + final Map<Class<?>, Class<?>> classCache = validatorContext.getFactory().getUnwrappedClassCache(); + Class<?> unwrappedClass = classCache.get(beanClass); + if (unwrappedClass == null) { + unwrappedClass = Proxies.classFor(beanClass); + classCache.putIfAbsent(beanClass, unwrappedClass); + } + return (BeanD<O>) validatorContext.getDescriptorManager().getBeanDescriptor(unwrappedClass); } final ConstraintViolationImpl<T> createViolation(String messageTemplate, ConstraintValidatorContextImpl<T> context, http://git-wip-us.apache.org/repos/asf/bval/blob/0e7541f3/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java b/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java index b6906f6..d15d639 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java @@ -31,8 +31,8 @@ public final class Proxies { KNOWN_PROXY_CLASSNAMES = Collections.unmodifiableSet(s); } - // get rid of proxies which probably contains wrong annotation metamodel - public static <T> Class<?> classFor(final Class<?> clazz) { // TODO: do we want a SPI with impl for guice, owb, openejb, ...? + // get rid of proxies which probably contains wrong annotation metamodel - note: it is "slow", cache the result! + public static Class<?> classFor(final Class<?> clazz) { // TODO: do we want a SPI with impl for guice, owb, openejb, ...? if (isProxyClass(clazz)) { final Class<?> parent = clazz.getSuperclass(); if (parent != null) {
