summaryrefslogtreecommitdiffstats
path: root/weaver5/java5-src
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2017-09-28 16:03:17 -0700
committerAndy Clement <aclement@pivotal.io>2017-10-20 13:11:32 -0700
commite908c89ef235e55519fa37042d156605c4366e35 (patch)
tree3279a11a5efdb65614c87adc1d093f3bdbf54ef7 /weaver5/java5-src
parentd2659f6c5823e321fec4b6021c2524f1c259527a (diff)
downloadaspectj-e908c89ef235e55519fa37042d156605c4366e35.tar.gz
aspectj-e908c89ef235e55519fa37042d156605c4366e35.zip
Fixes Bug 525293 - Spring AOP could be faster
Multiple changes here: - annotation unpacking is smarter and if it only needs runtime retention annotations it uses reflection and doesn't unpack the bytes to discover class level retention annotations. - Reflection worlds are shared if for the same classloader.
Diffstat (limited to 'weaver5/java5-src')
-rw-r--r--weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java142
1 files changed, 69 insertions, 73 deletions
diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
index a978d9605..016becf87 100644
--- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
+++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java
@@ -1,13 +1,10 @@
/* *******************************************************************
- * Copyright (c) 2005 Contributors.
+ * Copyright (c) 2005, 2017 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Adrian Colyer Initial implementation
* ******************************************************************/
package org.aspectj.weaver.reflect;
@@ -17,15 +14,13 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
import org.aspectj.apache.bcel.classfile.AnnotationDefault;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.LocalVariable;
import org.aspectj.apache.bcel.classfile.LocalVariableTable;
+import org.aspectj.apache.bcel.util.ClassLoaderRepository;
import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository;
import org.aspectj.apache.bcel.util.Repository;
import org.aspectj.weaver.AnnotationAJ;
@@ -36,36 +31,44 @@ import org.aspectj.weaver.bcel.BcelAnnotation;
import org.aspectj.weaver.bcel.BcelWeakClassLoaderReference;
/**
- * Find the given annotation (if present) on the given object
*
+ * @author Adrian Colyer
+ * @author Andy Clement
*/
public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
+ public static final ResolvedType[][] NO_PARAMETER_ANNOTATIONS = new ResolvedType[][] {};
+
private Repository bcelRepository;
private BcelWeakClassLoaderReference classLoaderRef;
private World world;
+ private static boolean useCachingClassLoaderRepository;
+
+ static {
+ try {
+ useCachingClassLoaderRepository = System.getProperty("Xset:bcelRepositoryCaching","true").equalsIgnoreCase("true");
+ } catch (Throwable t) {
+ useCachingClassLoaderRepository = false;
+ }
+ }
// must have no-arg constructor for reflective construction
public Java15AnnotationFinder() {
}
public void setClassLoader(ClassLoader aLoader) {
- // TODO: No easy way to ask the world factory for the right kind of
- // repository so
- // default to the safe one! (pr160674)
this.classLoaderRef = new BcelWeakClassLoaderReference(aLoader);
- this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef);
+ if (useCachingClassLoaderRepository) {
+ this.bcelRepository = new ClassLoaderRepository(classLoaderRef);
+ } else {
+ this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef);
+ }
}
public void setWorld(World aWorld) {
this.world = aWorld;
}
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.weaver.reflect.AnnotationFinder#getAnnotation(org.aspectj .weaver.ResolvedType, java.lang.Object)
- */
public Object getAnnotation(ResolvedType annotationType, Object onObject) {
try {
Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) Class.forName(annotationType.getName(),
@@ -155,7 +158,6 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
} catch (ClassNotFoundException cnfEx) {
// just use reflection then
}
-
return null;
}
@@ -186,80 +188,76 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
} catch (ClassNotFoundException cnfEx) {
// just use reflection then
}
-
return null;
}
- public Set getAnnotations(Member onMember) {
- if (!(onMember instanceof AccessibleObject))
- return Collections.EMPTY_SET;
- // here we really want both the runtime visible AND the class visible
- // annotations
- // so we bail out to Bcel and then chuck away the JavaClass so that we
- // don't hog
- // memory.
- try {
- JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass());
- org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0];
- if (onMember instanceof Method) {
- org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember);
- if (bcelMethod == null) {
- // fallback on reflection - see pr220430
- // System.err.println(
- // "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '"
- // +
- // onMember.getName()+"' in class '"+jc.getClassName()+"'");
- } else {
- anns = bcelMethod.getAnnotations();
+ public ResolvedType[] getAnnotations(Member onMember, boolean areRuntimeAnnotationsSufficient) {
+ if (!(onMember instanceof AccessibleObject)) {
+ return ResolvedType.NONE;
+ }
+ // If annotations with class level retention are required then we need to open
+ // open the class file. If only runtime retention annotations are required
+ // we can just use reflection.
+ if (!areRuntimeAnnotationsSufficient) {
+ try {
+ JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass());
+ org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = null;
+ if (onMember instanceof Method) {
+ org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember);
+ if (bcelMethod != null) {
+ anns = bcelMethod.getAnnotations();
+ }
+ } else if (onMember instanceof Constructor) {
+ org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember);
+ anns = bcelCons.getAnnotations();
+ } else if (onMember instanceof Field) {
+ org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember);
+ anns = bcelField.getAnnotations();
}
- } else if (onMember instanceof Constructor) {
- org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember);
- anns = bcelCons.getAnnotations();
- } else if (onMember instanceof Field) {
- org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember);
- anns = bcelField.getAnnotations();
- }
- // the answer is cached and we don't want to hold on to memory
- bcelRepository.clear();
- // OPTIMIZE make this a constant 0 size array
- if (anns == null)
- anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0];
- // convert to our Annotation type
- Set<ResolvedType> annSet = new HashSet<ResolvedType>();
- for (int i = 0; i < anns.length; i++) {
- annSet.add(world.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())));
+ // the answer is cached and we don't want to hold on to memory
+ bcelRepository.clear();
+ if (anns == null || anns.length == 0) {
+ return ResolvedType.NONE;
+ }
+ ResolvedType[] annotationTypes = new ResolvedType[anns.length];
+ for (int i = 0; i < anns.length; i++) {
+ annotationTypes[i] = world.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature()));
+ }
+ return annotationTypes;
+ } catch (ClassNotFoundException cnfEx) {
+ // just use reflection then
}
- return annSet;
- } catch (ClassNotFoundException cnfEx) {
- // just use reflection then
}
AccessibleObject ao = (AccessibleObject) onMember;
Annotation[] anns = ao.getDeclaredAnnotations();
- Set<UnresolvedType> annSet = new HashSet<UnresolvedType>();
+ if (anns.length == 0) {
+ return ResolvedType.NONE;
+ }
+ ResolvedType[] annotationTypes = new ResolvedType[anns.length];
for (int i = 0; i < anns.length; i++) {
- annSet.add(UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world));
+ annotationTypes[i] = UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world);
}
- return annSet;
+ return annotationTypes;
}
public ResolvedType[] getAnnotations(Class forClass, World inWorld) {
// here we really want both the runtime visible AND the class visible
- // annotations
- // so we bail out to Bcel and then chuck away the JavaClass so that we
- // don't hog
- // memory.
+ // annotations so we bail out to Bcel and then chuck away the JavaClass so that we
+ // don't hog memory.
try {
JavaClass jc = bcelRepository.loadClass(forClass);
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = jc.getAnnotations();
bcelRepository.clear();
- if (anns == null)
+ if (anns == null) {
return ResolvedType.NONE;
- ResolvedType[] ret = new ResolvedType[anns.length];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = inWorld.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature()));
+ } else {
+ ResolvedType[] ret = new ResolvedType[anns.length];
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = inWorld.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature()));
+ }
+ return ret;
}
- return ret;
} catch (ClassNotFoundException cnfEx) {
// just use reflection then
}
@@ -313,8 +311,6 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder {
return ret;
}
- public static final ResolvedType[][] NO_PARAMETER_ANNOTATIONS = new ResolvedType[][] {};
-
public ResolvedType[][] getParameterAnnotationTypes(Member onMember) {
if (!(onMember instanceof AccessibleObject))
return NO_PARAMETER_ANNOTATIONS;