You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by rm...@apache.org on 2019/02/07 09:24:54 UTC

bval git commit: BVAL-170 ensure we don't go through class model for each call, cache Proxies.classFor result

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 <rm...@gmail.com>
Authored: Thu Feb 7 10:24:49 2019 +0100
Committer: Romain Manni-Bucau <rm...@gmail.com>
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) {