[jboss-cvs] JBossAS SVN: r86909 - in projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors: lang and 1 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Apr 7 06:21:28 EDT 2009
Author: jaikiran
Date: 2009-04-07 06:21:28 -0400 (Tue, 07 Apr 2009)
New Revision: 86909
Modified:
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/lang/ClassHelper.java
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java
Log:
EJBTHREE-1801 Performance improvement in the logic of InterceptorRegistry and InjectInterceptorsFactory
Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java 2009-04-07 10:19:35 UTC (rev 86908)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java 2009-04-07 10:21:28 UTC (rev 86909)
@@ -30,6 +30,7 @@
import javax.interceptor.AroundInvoke;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.ExcludeDefaultInterceptors;
+import javax.interceptor.InvocationContext;
import org.jboss.aop.Advisor;
import org.jboss.aop.InstanceAdvisor;
@@ -51,12 +52,12 @@
public class InjectInterceptorsFactory extends AbstractInterceptorFactory
{
private static final Logger log = Logger.getLogger(InjectInterceptorsFactory.class);
-
+
public InjectInterceptorsFactory()
{
log.debug("new InjectInterceptorsFactory");
}
-
+
/**
* Generate the proper interceptor chain based on the spec interceptors.
*/
@@ -66,9 +67,9 @@
assert advisor != null;
assert instanceAdvisor != null;
assert jp instanceof MethodJoinpoint || jp instanceof ConstructorJoinpoint;
-
+
log.debug("Create interceptor chain for " + instanceAdvisor.getClass().getName() + "@" + System.identityHashCode(instanceAdvisor) + " on " + jp);
-
+
/*
defaultInterceptors = ...;
classInterceptors = ...;
@@ -78,9 +79,9 @@
if(jp instanceof MethodJoinpoint)
{
// aroundInvoke
-
+
Method method = ((MethodJoinpoint) jp).getMethod();
-
+
if(advisor instanceof ManagedObjectAdvisor)
{
AbstractContainer<?, ?> container = AbstractContainer.getContainer(advisor);
@@ -91,12 +92,14 @@
for (Class<?> interceptorClass : interceptorClasses)
{
ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor);
- for (Method interceptorMethod : ClassHelper.getAllMethods(interceptorClass))
+ // Get all public/private/protected/package access methods of signature:
+ // Object <MethodName> (InvocationContext)
+ Method[] possibleInterceptorMethods = ClassHelper.getMethods(interceptorClass, Object.class,new Class<?>[] {InvocationContext.class});
+ for (Method interceptorMethod : possibleInterceptorMethods)
{
- if (!ClassHelper.isOverridden(interceptorClass, interceptorMethod))
+ if (interceptorAdvisor.isAnnotationPresent(interceptorClass, interceptorMethod, AroundInvoke.class))
{
- if (interceptorAdvisor
- .isAnnotationPresent(interceptorClass, interceptorMethod, AroundInvoke.class))
+ if (!ClassHelper.isOverridden(interceptorMethod, possibleInterceptorMethods))
{
interceptors.add(new EJB3InterceptorInterceptor(interceptorClass, interceptorMethod));
}
@@ -105,11 +108,14 @@
}
}
Class<?> beanClass = advisor.getClazz();
- for(Method beanMethod : ClassHelper.getAllMethods(beanClass))
+ // Get all public/private/protected/package access methods of signature:
+ // Object <MethodName> (InvocationContext)
+ Method[] possibleAroundInvokeMethods = ClassHelper.getMethods(beanClass, Object.class, new Class<?>[] {InvocationContext.class});
+ for(Method beanMethod : possibleAroundInvokeMethods)
{
- if (!ClassHelper.isOverridden(beanClass, beanMethod))
+ if(advisor.hasAnnotation(beanMethod, AroundInvoke.class))
{
- if(advisor.hasAnnotation(beanMethod, AroundInvoke.class))
+ if (!ClassHelper.isOverridden(beanMethod, possibleAroundInvokeMethods))
{
interceptors.add(new BusinessMethodBeanMethodInterceptor(beanMethod));
}
@@ -117,7 +123,7 @@
}
return new InterceptorSequencer(interceptors);
}
-
+
List<Interceptor> interceptors = new ArrayList<Interceptor>() {
private static final long serialVersionUID = 1L;
@@ -134,9 +140,9 @@
interceptors.addAll(InterceptorsFactory.getClassInterceptors(instanceAdvisor));
interceptors.addAll(InterceptorsFactory.getBusinessMethodInterceptors(instanceAdvisor, method));
interceptors.addAll(InterceptorsFactory.getBeanInterceptors(instanceAdvisor));
-
+
log.debug("interceptors " + interceptors);
-
+
// TODO: total ordering (EJB 3 12.8.2.1 and @Interceptors with all)
// FIXME
return new InterceptorSequencer(interceptors);
@@ -144,22 +150,22 @@
else
{
// postConstruct
-
+
if(advisor instanceof ManagedObjectAdvisor)
{
log.warn("EJBTHREE-1246: Do not use InjectInterceptorsFactory with a ManagedObjectAdvisor for lifecycle callbacks, should be done by the container");
// Note that the container delegates it to ejb3-callbacks or the MC bean factory
return new NopInterceptor();
}
-
+
List<Interceptor> interceptors = InterceptorsFactory.getLifeCycleInterceptors(instanceAdvisor, PostConstruct.class);
-
+
log.debug("PostConstruct interceptors " + interceptors);
-
+
return new InterceptorSequencer(interceptors);
}
}
-
+
@Override
public Object createPerJoinpoint(Advisor advisor, Joinpoint jp)
{
@@ -173,12 +179,12 @@
// Can't do that, because the instance interceptors are not there yet (InterceptorsFactory)
// so the hack is in ManagedObjectAdvisor.createInterceptorChain.
}
-
+
private static final boolean isExcludeClassInterceptors(Advisor advisor, Method method)
{
return advisor.hasAnnotation(method, ExcludeClassInterceptors.class) || advisor.resolveAnnotation(ExcludeClassInterceptors.class) != null;
}
-
+
private static final boolean isExcludeDefaultInterceptors(Advisor advisor, Method method)
{
return advisor.hasAnnotation(method, ExcludeDefaultInterceptors.class) || advisor.resolveAnnotation(ExcludeDefaultInterceptors.class) != null;
Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/lang/ClassHelper.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/lang/ClassHelper.java 2009-04-07 10:19:35 UTC (rev 86908)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/lang/ClassHelper.java 2009-04-07 10:21:28 UTC (rev 86909)
@@ -26,8 +26,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Methods which should have been in Class.
@@ -70,13 +72,13 @@
}
return true;
}
-
+
/**
* Returns all public, private and package protected methods including
* inherited ones.
- *
+ *
* (Slow method)
- *
+ *
* @param cls
* @return
*/
@@ -86,15 +88,15 @@
populateAllMethods(cls, list);
return list.toArray(new Method[0]);
}
-
+
/**
* Returns the method with the specified method name.
- *
+ *
* (Slow method)
- *
+ *
* @param methodName
* @return
- * @throws NoSuchMethodException
+ * @throws NoSuchMethodException
*/
public static Method getMethod(Class<?> cls, String methodName) throws NoSuchMethodException
{
@@ -116,15 +118,15 @@
throw new NoSuchMethodException("No method named " + methodName + " in " + cls + " (or super classes)");
}
}
-
+
/**
* Returns the method with the specified method name and parameters.
- *
+ *
* @param cls
* @param methodName
* @param params
* @return
- * @throws NoSuchMethodException
+ * @throws NoSuchMethodException
*/
public static Method getMethod(Class<?> cls, String methodName, Class<?> ... params) throws NoSuchMethodException
{
@@ -140,7 +142,7 @@
}
return m;
}
-
+
private static Method getDeclaredMethod(Class<?> cls, String methodName, Class<?> ... params)
{
Method methods[] = SecurityActions.getDeclaredMethods(cls);
@@ -157,7 +159,7 @@
return method;
}
}
-
+
try
{
return SecurityActions.getDeclaredMethod(cls, methodName, params);
@@ -170,24 +172,24 @@
{
return null;
}
-
+
return getDeclaredMethod(cls.getSuperclass(), methodName, params);
}
/**
* Returns all public, private and package protected methods including
* inherited ones in a map indexed by name.
- *
+ *
* (Slow method)
- *
+ *
* @param cls
* @return
*/
- public static Map<String, List<Method>> getAllMethodsMap(Class<?> cls)
+ public static Map<String, List<Method>> getAllMethodsMap(Class<?> cls)
{
- Map<String, List<Method>> methodMap = new HashMap<String, List<Method>>();
+ Map<String, List<Method>> methodMap = new HashMap<String, List<Method>>();
ArrayList<Method> list = new ArrayList<Method>();
populateAllMethods(cls, list);
-
+
for (Method method : list)
{
List<Method> methods = methodMap.get(method.getName());
@@ -200,13 +202,13 @@
}
return methodMap;
}
-
+
/**
* Find all methods starting with the most general super class.
* (See 12.4.1 bullet 4)
- *
+ *
* This makes the class unusable for other scenarios.
- *
+ *
* @param cls
* @param methods
*/
@@ -218,7 +220,7 @@
methods.add(method);
}
- public static boolean isOverridden(Class<?> icptr, Method method)
+ public static boolean isOverridden(Class<?> icptr, Method method)
{
if(Modifier.isPrivate(method.getModifiers()))
return false;
@@ -236,4 +238,104 @@
throw new RuntimeException(e);
}
}
+
+ /**
+ * Returns all (public,private, package, protected) methods belonging to the
+ * <code>klass</code> and its superclasses whose params match the <code>paramTypes</code>
+ * and whose return type is <code>returnType</code>
+ *
+ * @param klass
+ * @param paramTypes
+ * @return
+ */
+ public static Method[] getMethods(Class<?> klass, Class<?> returnType, Class<?>...paramTypes)
+ {
+ // the methods which will be returned, after match
+ Set<Method> methodsAcceptingParamTypes = new LinkedHashSet<Method>();
+
+ // All (public,private,protected,package) methods on the klass and its superclasses.
+ // Does NOT take into account the param types yet.
+ Method[] allMethodsOfClass = getAllMethods(klass);
+
+ // Filter out relevant methods based on param types
+ for (Method method : allMethodsOfClass)
+ {
+ // compare return type
+ if (!method.getReturnType().equals(returnType))
+ {
+ // doesn't match, skip
+ continue;
+ }
+
+ if (method.getParameterTypes().length != paramTypes.length)
+ {
+ // irrelevant method, skip and move to next
+ continue;
+ }
+ // if params match, then the method is relevant, else move to next
+ if (checkParameters(method.getParameterTypes(), paramTypes))
+ {
+ // matching method (accepting the param types). Add to collection to
+ // be returned
+ methodsAcceptingParamTypes.add(method);
+ }
+
+ }
+ return methodsAcceptingParamTypes.toArray(new Method[methodsAcceptingParamTypes.size()]);
+ }
+
+ /**
+ * Checks whether the <code>method</code> is overriden by any of the methods
+ * *in the passed collection of <code>methods</code>*. Returns true if the method
+ * is overriden by any of the passed methods, else returns false.
+ *
+ * @param method
+ * @param methods
+ * @return
+ */
+ public static boolean isOverridden(Method method, Method... methods)
+ {
+
+ for (Method someMethod : methods)
+ {
+ // first compare the names, if not equal then no
+ // point in do other checks.
+ if (!method.getName().equals(someMethod.getName()))
+ {
+ // skip and move to next
+ continue;
+ }
+
+ // Now check the params
+ if (method.getParameterTypes().length != someMethod.getParameterTypes().length)
+ {
+ // skip
+ continue;
+ }
+ // param types
+ if (!checkParameters(method.getParameterTypes(), someMethod.getParameterTypes()))
+ {
+ // skip
+ continue;
+ }
+ // check the declaring class, if it's the same, then
+ // we are checking the method on the same class, so NOT overridden
+ if (method.getDeclaringClass().equals(someMethod.getDeclaringClass()))
+ {
+ // skip
+ continue;
+ }
+ // the final check to see whether the declaring class
+ // of the method being compared is a superclass of the other method.
+ // If yes, then the method is overridden
+ if (method.getDeclaringClass().isAssignableFrom(someMethod.getDeclaringClass()))
+ {
+ // yes, this method is overridden
+ return true;
+ }
+ }
+ // the method is not overridden
+ return false;
+ }
+
}
Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java 2009-04-07 10:19:35 UTC (rev 86908)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java 2009-04-07 10:21:28 UTC (rev 86909)
@@ -152,7 +152,11 @@
}
Class<?> beanClass = advisor.getClazz();
- for(Method beanMethod : ClassHelper.getAllMethods(beanClass))
+ // EJB3 spec says in section 12.7
+ // "A business method interceptor method may be defined to apply to a specific *business method*
+ // invocation, rather than to all of the business methods of the bean class."
+ // So all we need are "public" methods.
+ for(Method beanMethod : beanClass.getMethods())
{
interceptorsAnnotation = (Interceptors) advisor.resolveAnnotation(beanMethod, Interceptors.class);
List<Class<?>> methodInterceptorClasses = new ArrayList<Class<?>>();
@@ -174,6 +178,7 @@
// Total ordering (EJB 3 12.8.2.1)
// TODO: @Interceptors with all?
+
InterceptorOrder order = (InterceptorOrder) advisor.resolveAnnotation(beanMethod, InterceptorOrder.class);
if(order == null)
order = (InterceptorOrder) advisor.resolveAnnotation(InterceptorOrder.class);
More information about the jboss-cvs-commits
mailing list