[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