Author: markt
Date: Wed Sep 7 18:35:15 2011
New Revision: 1166308
URL: http://svn.apache.org/viewvc?rev=1166308&view=rev
Log:
Add an annotation cache to the <code>DefaultInstanceManager</code> that
improves performance for applications that make use of a lot of non-poolable
objects (e.g. tag files) that need to be scanned for annotations when created.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 7 18:35:15 2011
@@ -1 +1 @@
-/tomcat/trunk:1156171,1156276,1156304,1156530,1156602,1157015,1157018,1157151,1157198,1157204,1157810,1157832,1157834,1157847,1157908,1157939,1158155,1158160,1158176,1158195,1158198-1158199,1158227,1158331,1158334-1158335,1158426,1160347,1160592,1160611,1160619,1160626,1160639,1160652,1160720-1160721,1160772,1160774,1160776,1161303,1161310,1161322,1161339,1161486,1161540,1161549,1161584,1162082,1162149,1162169,1162721,1162769,1162836,1162932,1163630,1164419,1164438,1164469,1164480,1164567,1165234,1166077
+/tomcat/trunk:1156171,1156276,1156304,1156530,1156602,1157015,1157018,1157151,1157198,1157204,1157810,1157832,1157834,1157847,1157908,1157939,1158155,1158160,1158176,1158195,1158198-1158199,1158227,1158331,1158334-1158335,1158426,1160347,1160592,1160611,1160619,1160626,1160639,1160652,1160720-1160721,1160772,1160774,1160776,1161303,1161310,1161322,1161339,1161486,1161540,1161549,1161584,1162082,1162149,1162169,1162721,1162769,1162836,1162932,1163630,1164419,1164438,1164469,1164480,1164567,1165234,1166077,1166290
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java?rev=1166308&r1=1166307&r2=1166308&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
(original)
+++
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
Wed Sep 7 18:35:15 2011
@@ -21,6 +21,7 @@ package org.apache.catalina.core;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -29,8 +30,11 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -65,6 +69,8 @@ public class DefaultInstanceManager impl
private Properties restrictedFilters = new Properties();
private Properties restrictedListeners = new Properties();
private Properties restrictedServlets = new Properties();
+ private Map<Class<?>,List<AnnotationCacheEntry>> annotationCache =
+ new ConcurrentHashMap<Class<?>, List<AnnotationCacheEntry>>();
public DefaultInstanceManager(Context context, Map<String, Map<String,
String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader
containerClassLoader) {
classLoader = catalinaContext.getLoader().getClassLoader();
@@ -276,97 +282,138 @@ public class DefaultInstanceManager impl
Class<?> clazz = instance.getClass();
while (clazz != null) {
- // Initialize fields annotations
- Field[] fields = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz2 = clazz;
- fields = AccessController.doPrivileged(
- new PrivilegedAction<Field[]>(){
- @Override
- public Field[] run(){
- return clazz2.getDeclaredFields();
+ List<AnnotationCacheEntry> annotations =
annotationCache.get(clazz);
+ if (annotations == null) {
+ annotations = new ArrayList<AnnotationCacheEntry>();
+ // Initialize fields annotations
+ Field[] fields = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ final Class<?> clazz2 = clazz;
+ fields = AccessController.doPrivileged(
+ new PrivilegedAction<Field[]>(){
+ @Override
+ public Field[] run(){
+ return clazz2.getDeclaredFields();
+ }
+ });
+ } else {
+ fields = clazz.getDeclaredFields();
+ }
+ for (Field field : fields) {
+ if (injections != null &&
injections.containsKey(field.getName())) {
+ lookupFieldResource(context, instance, field,
+ injections.get(field.getName()), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ injections.get(field.getName())));
+ } else if (field.isAnnotationPresent(Resource.class)) {
+ Resource annotation =
field.getAnnotation(Resource.class);
+ lookupFieldResource(context, instance, field,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ annotation.name()));
+ } else if (field.isAnnotationPresent(EJB.class)) {
+ EJB annotation = field.getAnnotation(EJB.class);
+ lookupFieldResource(context, instance, field,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ annotation.name()));
+ } else if (field.isAnnotationPresent(WebServiceRef.class))
{
+ WebServiceRef annotation =
+ field.getAnnotation(WebServiceRef.class);
+ lookupFieldResource(context, instance, field,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ annotation.name()));
+ } else if
(field.isAnnotationPresent(PersistenceContext.class)) {
+ PersistenceContext annotation =
+ field.getAnnotation(PersistenceContext.class);
+ lookupFieldResource(context, instance, field,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ annotation.name()));
+ } else if
(field.isAnnotationPresent(PersistenceUnit.class)) {
+ PersistenceUnit annotation =
+ field.getAnnotation(PersistenceUnit.class);
+ lookupFieldResource(context, instance, field,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(field,
+ annotation.name()));
}
- });
- } else {
- fields = clazz.getDeclaredFields();
- }
- for (Field field : fields) {
- if (injections != null &&
injections.containsKey(field.getName())) {
- lookupFieldResource(context, instance, field,
- injections.get(field.getName()), clazz);
- } else if (field.isAnnotationPresent(Resource.class)) {
- Resource annotation = field.getAnnotation(Resource.class);
- lookupFieldResource(context, instance, field,
- annotation.name(), clazz);
- } else if (field.isAnnotationPresent(EJB.class)) {
- EJB annotation = field.getAnnotation(EJB.class);
- lookupFieldResource(context, instance, field,
- annotation.name(), clazz);
- } else if (field.isAnnotationPresent(WebServiceRef.class)) {
- WebServiceRef annotation =
- field.getAnnotation(WebServiceRef.class);
- lookupFieldResource(context, instance, field,
- annotation.name(), clazz);
- } else if
(field.isAnnotationPresent(PersistenceContext.class)) {
- PersistenceContext annotation =
- field.getAnnotation(PersistenceContext.class);
- lookupFieldResource(context, instance, field,
- annotation.name(), clazz);
- } else if (field.isAnnotationPresent(PersistenceUnit.class)) {
- PersistenceUnit annotation =
- field.getAnnotation(PersistenceUnit.class);
- lookupFieldResource(context, instance, field,
- annotation.name(), clazz);
}
- }
-
- // Initialize methods annotations
- Method[] methods = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz2 = clazz;
- methods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>(){
- @Override
- public Method[] run(){
- return clazz2.getDeclaredMethods();
+
+ // Initialize methods annotations
+ Method[] methods = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ final Class<?> clazz2 = clazz;
+ methods = AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>(){
+ @Override
+ public Method[] run(){
+ return clazz2.getDeclaredMethods();
+ }
+ });
+ } else {
+ methods = clazz.getDeclaredMethods();
+ }
+ for (Method method : methods) {
+ String methodName = method.getName();
+ if (injections != null && methodName.startsWith("set") &&
methodName.length() > 3) {
+ String fieldName =
Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
+ if (injections.containsKey(fieldName)) {
+ lookupMethodResource(context, instance, method,
+ injections.get(fieldName), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ injections.get(method.getName())));
+ break;
+ }
}
- });
- } else {
- methods = clazz.getDeclaredMethods();
- }
- for (Method method : methods) {
- String methodName = method.getName();
- if (injections != null && methodName.startsWith("set") &&
methodName.length() > 3) {
- String fieldName =
Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
- if (injections.containsKey(fieldName)) {
+ if (method.isAnnotationPresent(Resource.class)) {
+ Resource annotation =
method.getAnnotation(Resource.class);
+ lookupMethodResource(context, instance, method,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ annotation.name()));
+ } else if (method.isAnnotationPresent(EJB.class)) {
+ EJB annotation = method.getAnnotation(EJB.class);
lookupMethodResource(context, instance, method,
- injections.get(fieldName), clazz);
- break;
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ annotation.name()));
+ } else if
(method.isAnnotationPresent(WebServiceRef.class)) {
+ WebServiceRef annotation =
+ method.getAnnotation(WebServiceRef.class);
+ lookupMethodResource(context, instance, method,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ annotation.name()));
+ } else if
(method.isAnnotationPresent(PersistenceContext.class)) {
+ PersistenceContext annotation =
+ method.getAnnotation(PersistenceContext.class);
+ lookupMethodResource(context, instance, method,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ annotation.name()));
+ } else if
(method.isAnnotationPresent(PersistenceUnit.class)) {
+ PersistenceUnit annotation =
+ method.getAnnotation(PersistenceUnit.class);
+ lookupMethodResource(context, instance, method,
+ annotation.name(), clazz);
+ annotations.add(new AnnotationCacheEntry(method,
+ annotation.name()));
}
}
- if (method.isAnnotationPresent(Resource.class)) {
- Resource annotation = method.getAnnotation(Resource.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
- } else if (method.isAnnotationPresent(EJB.class)) {
- EJB annotation = method.getAnnotation(EJB.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
- } else if (method.isAnnotationPresent(WebServiceRef.class)) {
- WebServiceRef annotation =
- method.getAnnotation(WebServiceRef.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
- } else if
(method.isAnnotationPresent(PersistenceContext.class)) {
- PersistenceContext annotation =
- method.getAnnotation(PersistenceContext.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
- } else if (method.isAnnotationPresent(PersistenceUnit.class)) {
- PersistenceUnit annotation =
- method.getAnnotation(PersistenceUnit.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
+ annotationCache.put(clazz, annotations);
+ } else {
+ for (AnnotationCacheEntry entry : annotations) {
+ if (entry.getAccessibleObject() instanceof Method) {
+ lookupMethodResource(context, instance,
+ (Method) entry.getAccessibleObject(),
+ entry.getName(), clazz);
+ } else {
+ lookupFieldResource(context, instance,
+ (Field) entry.getAccessibleObject(),
+ entry.getName(), clazz);
+ }
}
}
clazz = clazz.getSuperclass();
@@ -529,4 +576,23 @@ public class DefaultInstanceManager impl
}
return jndiName;
}
+
+ private static final class AnnotationCacheEntry {
+ private final AccessibleObject accessibleObject;
+ private final String name;
+
+ public AnnotationCacheEntry(AccessibleObject accessibleObject,
+ String name) {
+ this.accessibleObject = accessibleObject;
+ this.name = name;
+ }
+
+ public AccessibleObject getAccessibleObject() {
+ return accessibleObject;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
}
Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1166308&r1=1166307&r2=1166308&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Sep 7 18:35:15 2011
@@ -88,6 +88,12 @@
session tracking modes from being defined in web.xml when running under
a security manager. (markt)
</fix>
+ <add>
+ Add an annotation cache to the <code>DefaultInstanceManager</code> that
+ improves performance for applications that make use of a lot of
+ non-poolable objects (e.g. tag files) that need to be scanned for
+ annotations when created. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]