Repository: deltaspike Updated Branches: refs/heads/master 0617f2c23 -> ec5ce5dd8
DELTASPIKE-1170 Proxy should be invocationHandler class independent Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/ec5ce5dd Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/ec5ce5dd Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/ec5ce5dd Branch: refs/heads/master Commit: ec5ce5dd8231093b04cf4425c7225b114273e917 Parents: 0617f2c Author: Thomas Andraschko <[email protected]> Authored: Wed Jun 8 08:57:30 2016 +0200 Committer: Thomas Andraschko <[email protected]> Committed: Wed Jun 8 08:57:30 2016 +0200 ---------------------------------------------------------------------- .../AbstractManualInvocationHandler.java | 71 +++--------- .../impl/invocation/InterceptorLookup.java | 109 +++++++++++++++++++ 2 files changed, 126 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ec5ce5dd/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java index 3df3dbf..b105206 100644 --- a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java @@ -18,26 +18,26 @@ */ package org.apache.deltaspike.proxy.impl.invocation; -import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.List; import javax.enterprise.inject.Typed; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.InterceptionType; import javax.enterprise.inject.spi.Interceptor; -import javax.interceptor.InterceptorBinding; -import org.apache.deltaspike.core.api.provider.BeanManagerProvider; +import org.apache.deltaspike.core.api.provider.BeanProvider; @Typed public abstract class AbstractManualInvocationHandler implements InvocationHandler { + private volatile Boolean initialized; + private InterceptorLookup interceptorLookup; + @Override public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable { + lazyInit(); + // check if interceptors are defined, otherwise just call the original logik - List<Interceptor<?>> interceptors = resolveInterceptors(proxy, method); + List<Interceptor<?>> interceptors = interceptorLookup.lookup(proxy, method); if (interceptors != null && interceptors.size() > 0) { try @@ -74,61 +74,24 @@ public abstract class AbstractManualInvocationHandler implements InvocationHandl */ protected abstract Object proceedOriginal(Object proxy, Method method, Object[] parameters) throws Throwable; - protected List<Interceptor<?>> resolveInterceptors(Object instance, Method method) + + + private void lazyInit() { - BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); - - Annotation[] interceptorBindings = extractInterceptorBindings(beanManager, instance, method); - if (interceptorBindings.length > 0) + if (this.initialized == null) { - return beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE, interceptorBindings); + init(); } - - return null; } - protected Annotation[] extractInterceptorBindings(BeanManager beanManager, Object instance, Method method) - { - ArrayList<Annotation> bindings = new ArrayList<Annotation>(); - - addInterceptorBindings(beanManager, bindings, instance.getClass().getDeclaredAnnotations()); - addInterceptorBindings(beanManager, bindings, method.getDeclaredAnnotations()); - - return bindings.toArray(new Annotation[bindings.size()]); - } - - protected void addInterceptorBindings(BeanManager beanManager, ArrayList<Annotation> bindings, - Annotation[] declaredAnnotations) + private synchronized void init() { - for (Annotation annotation : declaredAnnotations) + // switch into paranoia mode + if (this.initialized == null) { - if (bindings.contains(annotation)) - { - continue; - } - - Class<? extends Annotation> annotationType = annotation.annotationType(); - - if (annotationType.isAnnotationPresent(InterceptorBinding.class)) - { - bindings.add(annotation); - } + this.initialized = true; - if (beanManager.isStereotype(annotationType)) - { - for (Annotation subAnnotation : annotationType.getDeclaredAnnotations()) - { - if (bindings.contains(subAnnotation)) - { - continue; - } - - if (subAnnotation.annotationType().isAnnotationPresent(InterceptorBinding.class)) - { - bindings.add(subAnnotation); - } - } - } + this.interceptorLookup = BeanProvider.getContextualReference(InterceptorLookup.class); } } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/ec5ce5dd/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptorLookup.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptorLookup.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptorLookup.java new file mode 100644 index 0000000..413ea45 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptorLookup.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.proxy.impl.invocation; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InterceptionType; +import javax.enterprise.inject.spi.Interceptor; +import javax.interceptor.InterceptorBinding; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; + +@ApplicationScoped +public class InterceptorLookup +{ + private final Map<Method, List<Interceptor<?>>> cache = new HashMap<Method, List<Interceptor<?>>>(); + + public List<Interceptor<?>> lookup(Object instance, Method method) + { + List<Interceptor<?>> interceptors = cache.get(method); + + if (interceptors == null) + { + interceptors = resolveInterceptors(instance, method); + cache.put(method, interceptors); + } + + return interceptors; + } + + protected List<Interceptor<?>> resolveInterceptors(Object instance, Method method) + { + BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); + + Annotation[] interceptorBindings = extractInterceptorBindings(beanManager, instance, method); + if (interceptorBindings.length > 0) + { + return beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE, interceptorBindings); + } + + return new ArrayList<Interceptor<?>>(); + } + + protected Annotation[] extractInterceptorBindings(BeanManager beanManager, Object instance, Method method) + { + ArrayList<Annotation> bindings = new ArrayList<Annotation>(); + + addInterceptorBindings(beanManager, bindings, instance.getClass().getDeclaredAnnotations()); + addInterceptorBindings(beanManager, bindings, method.getDeclaredAnnotations()); + + return bindings.toArray(new Annotation[bindings.size()]); + } + + protected void addInterceptorBindings(BeanManager beanManager, ArrayList<Annotation> bindings, + Annotation[] declaredAnnotations) + { + for (Annotation annotation : declaredAnnotations) + { + if (bindings.contains(annotation)) + { + continue; + } + + Class<? extends Annotation> annotationType = annotation.annotationType(); + + if (annotationType.isAnnotationPresent(InterceptorBinding.class)) + { + bindings.add(annotation); + } + + if (beanManager.isStereotype(annotationType)) + { + for (Annotation subAnnotation : annotationType.getDeclaredAnnotations()) + { + if (bindings.contains(subAnnotation)) + { + continue; + } + + if (subAnnotation.annotationType().isAnnotationPresent(InterceptorBinding.class)) + { + bindings.add(subAnnotation); + } + } + } + } + } +}
