You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2011/09/08 12:59:04 UTC
svn commit: r1166622 - in /tomcat/tc7.0.x/trunk: ./
java/org/apache/catalina/core/DefaultInstanceManager.java
Author: markt
Date: Thu Sep 8 10:59:04 2011
New Revision: 1166622
URL: http://svn.apache.org/viewvc?rev=1166622&view=rev
Log:
Add caching of postConstruct and preDestroy annotations
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep 8 10:59:04 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,1165247-1165248,1165253,1165273,1165282,1165309,1165331,1165338,1165347,1165360-1165361,1165367-1165368,1165602,1165608,1165677,1165693,1165721,1165723,1165728,1165730,1165738,1165746,1165765,1165777,1165918,1165921,1166077,1166150-1166151,1166290,1166366
+/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,1165247-1165248,1165253,1165273,1165282,1165309,1165331,1165338,1165347,1165360-1165361,1165367-1165368,1165602,1165608,1165677,1165693,1165721,1165723,1165728,1165730,1165738,1165746,1165765,1165777,1165918,1165921,1166077,1166150-1166151,1166290,1166366,1166620
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=1166622&r1=1166621&r2=1166622&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 Thu Sep 8 10:59:04 2011
@@ -141,6 +141,7 @@ public class DefaultInstanceManager impl
private Object newInstance(Object instance, Class<?> clazz) throws IllegalAccessException, InvocationTargetException, NamingException {
if (!ignoreAnnotations) {
Map<String, String> injections = injectionMap.get(clazz.getName());
+ populateAnnotationsCache(clazz, injections);
processAnnotations(instance, injections);
postConstruct(instance, clazz);
}
@@ -170,41 +171,18 @@ public class DefaultInstanceManager impl
postConstruct(instance, superClass);
}
- Method[] methods = null;
- if (Globals.IS_SECURITY_ENABLED) {
- methods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>(){
- @Override
- public Method[] run(){
- return clazz.getDeclaredMethods();
- }
- });
- } else {
- methods = clazz.getDeclaredMethods();
- }
- Method postConstruct = null;
- for (Method method : methods) {
- if (method.isAnnotationPresent(PostConstruct.class)) {
- if ((postConstruct != null)
- || (method.getParameterTypes().length != 0)
- || (Modifier.isStatic(method.getModifiers()))
- || (method.getExceptionTypes().length > 0)
- || (!method.getReturnType().getName().equals("void"))) {
- throw new IllegalArgumentException("Invalid PostConstruct annotation");
- }
- postConstruct = method;
- }
- }
-
// At the end the postconstruct annotated
// method is invoked
- if (postConstruct != null) {
- boolean accessibility = postConstruct.isAccessible();
- postConstruct.setAccessible(true);
- postConstruct.invoke(instance);
- postConstruct.setAccessible(accessibility);
+ List<AnnotationCacheEntry> annotations = annotationCache.get(clazz);
+ for (AnnotationCacheEntry entry : annotations) {
+ if (entry.getType() == AnnotationCacheEntryType.POST_CONSTRUCT) {
+ Method postConstruct = (Method) entry.getAccessibleObject();
+ boolean accessibility = postConstruct.isAccessible();
+ postConstruct.setAccessible(true);
+ postConstruct.invoke(instance);
+ postConstruct.setAccessible(accessibility);
+ }
}
-
}
@@ -224,64 +202,42 @@ public class DefaultInstanceManager impl
preDestroy(instance, superClass);
}
- Method[] methods;
- if (Globals.IS_SECURITY_ENABLED) {
- methods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>(){
- @Override
- public Method[] run(){
- return clazz.getDeclaredMethods();
- }
- });
- } else {
- methods = clazz.getDeclaredMethods();
- }
- Method preDestroy = null;
- for (Method method : methods) {
- if (method.isAnnotationPresent(PreDestroy.class)) {
- if ((method.getParameterTypes().length != 0)
- || (Modifier.isStatic(method.getModifiers()))
- || (method.getExceptionTypes().length > 0)
- || (!method.getReturnType().getName().equals("void"))) {
- throw new IllegalArgumentException("Invalid PreDestroy annotation");
- }
- preDestroy = method;
- break;
- }
- }
-
// At the end the postconstruct annotated
// method is invoked
- if (preDestroy != null) {
- boolean accessibility = preDestroy.isAccessible();
- preDestroy.setAccessible(true);
- preDestroy.invoke(instance);
- preDestroy.setAccessible(accessibility);
+ List<AnnotationCacheEntry> annotations = annotationCache.get(clazz);
+ for (AnnotationCacheEntry entry : annotations) {
+ if (entry.getType() == AnnotationCacheEntryType.PRE_DESTROY) {
+ Method preDestroy = (Method) entry.getAccessibleObject();
+ boolean accessibility = preDestroy.isAccessible();
+ preDestroy.setAccessible(true);
+ preDestroy.invoke(instance);
+ preDestroy.setAccessible(accessibility);
+ }
}
-
}
/**
- * Inject resources in specified instance.
+ * Make sure that the annotations cache has been populated for the provided
+ * class.
*
- * @param instance instance to inject into
- * @param injections map of injections for this class from xml deployment descriptor
+ * @param clazz clazz to populate annotations for
+ * @param injections map of injections for this class from xml deployment
+ * descriptor
* @throws IllegalAccessException if injection target is inaccessible
* @throws javax.naming.NamingException if value cannot be looked up in jndi
* @throws java.lang.reflect.InvocationTargetException
* if injection fails
*/
- protected void processAnnotations(Object instance, Map<String, String> injections)
- throws IllegalAccessException, InvocationTargetException, NamingException {
+ protected void populateAnnotationsCache(Class<?> clazz,
+ Map<String, String> injections) throws IllegalAccessException,
+ InvocationTargetException, NamingException {
if (context == null) {
// No resource injection
return;
}
- Class<?> clazz = instance.getClass();
-
while (clazz != null) {
List<AnnotationCacheEntry> annotations = annotationCache.get(clazz);
if (annotations == null) {
@@ -302,43 +258,37 @@ public class DefaultInstanceManager impl
}
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())));
+ injections.get(field.getName()),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
}
}
@@ -356,60 +306,121 @@ public class DefaultInstanceManager impl
} else {
methods = clazz.getDeclaredMethods();
}
+ Method postConstruct = null;
+ Method preDestroy = null;
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())));
+ injections.get(method.getName()),
+ AnnotationCacheEntryType.FIELD));
break;
}
}
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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} else if (method.isAnnotationPresent(EJB.class)) {
EJB annotation = method.getAnnotation(EJB.class);
- lookupMethodResource(context, instance, method,
- annotation.name(), clazz);
annotations.add(new AnnotationCacheEntry(method,
- annotation.name()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
} 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()));
+ annotation.name(),
+ AnnotationCacheEntryType.FIELD));
+ }
+
+ if (method.isAnnotationPresent(PostConstruct.class)) {
+ if ((postConstruct != null) ||
+ (method.getParameterTypes().length != 0) ||
+ (Modifier.isStatic(method.getModifiers())) ||
+ (method.getExceptionTypes().length > 0) ||
+ (!method.getReturnType().getName().equals("void"))) {
+ throw new IllegalArgumentException(
+ "Invalid PostConstruct annotation");
+ }
+ postConstruct = method;
+ }
+
+ if (method.isAnnotationPresent(PreDestroy.class)) {
+ if ((preDestroy != null ||
+ method.getParameterTypes().length != 0) ||
+ (Modifier.isStatic(method.getModifiers())) ||
+ (method.getExceptionTypes().length > 0) ||
+ (!method.getReturnType().getName().equals("void"))) {
+ throw new IllegalArgumentException(
+ "Invalid PreDestroy annotation");
+ }
+ preDestroy = method;
}
}
+ if (postConstruct != null) {
+ annotations.add(new AnnotationCacheEntry(postConstruct,
+ null, AnnotationCacheEntryType.POST_CONSTRUCT));
+ }
+ if (preDestroy != null) {
+ annotations.add(new AnnotationCacheEntry(preDestroy,
+ null, AnnotationCacheEntryType.PRE_DESTROY));
+ }
if (annotations.size() == 0) {
// Use common empty list to save memory
annotations = Collections.emptyList();
}
annotationCache.put(clazz, annotations);
} else {
- for (AnnotationCacheEntry entry : annotations) {
+ // If the annotations for this class have been cached, the
+ // annotations for all the super classes will have been cachced
+ // as well
+ break;
+ }
+ clazz = clazz.getSuperclass();
+ }
+ }
+
+
+ /**
+ * Inject resources in specified instance.
+ *
+ * @param instance instance to inject into
+ * @param injections map of injections for this class from xml deployment descriptor
+ * @throws IllegalAccessException if injection target is inaccessible
+ * @throws javax.naming.NamingException if value cannot be looked up in jndi
+ * @throws java.lang.reflect.InvocationTargetException
+ * if injection fails
+ */
+ protected void processAnnotations(Object instance, Map<String, String> injections)
+ throws IllegalAccessException, InvocationTargetException, NamingException {
+
+ if (context == null) {
+ // No resource injection
+ return;
+ }
+
+ Class<?> clazz = instance.getClass();
+
+ while (clazz != null) {
+ List<AnnotationCacheEntry> annotations = annotationCache.get(clazz);
+ for (AnnotationCacheEntry entry : annotations) {
+ if (entry.getType() == AnnotationCacheEntryType.FIELD) {
if (entry.getAccessibleObject() instanceof Method) {
lookupMethodResource(context, instance,
(Method) entry.getAccessibleObject(),
@@ -423,7 +434,6 @@ public class DefaultInstanceManager impl
}
clazz = clazz.getSuperclass();
}
-
}
@@ -585,11 +595,13 @@ public class DefaultInstanceManager impl
private static final class AnnotationCacheEntry {
private final AccessibleObject accessibleObject;
private final String name;
+ private final AnnotationCacheEntryType type;
public AnnotationCacheEntry(AccessibleObject accessibleObject,
- String name) {
+ String name, AnnotationCacheEntryType type) {
this.accessibleObject = accessibleObject;
this.name = name;
+ this.type = type;
}
public AccessibleObject getAccessibleObject() {
@@ -599,5 +611,12 @@ public class DefaultInstanceManager impl
public String getName() {
return name;
}
+ public AnnotationCacheEntryType getType() {
+ return type;
+ }
+ }
+
+ private static enum AnnotationCacheEntryType {
+ FIELD, POST_CONSTRUCT, PRE_DESTROY
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org