[jboss-cvs] JBossAS SVN: r92611 - in projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3: mdb and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Aug 20 10:46:41 EDT 2009


Author: jaikiran
Date: 2009-08-20 10:46:41 -0400 (Thu, 20 Aug 2009)
New Revision: 92611

Added:
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java
Modified:
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java
Log:
EJBTHREE-1896 Performance change - Creation of lifecycle callback interceptors will be done just once per bean context instead of repeating it multiple times for the same bean context

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java	2009-08-20 12:55:24 UTC (rev 92610)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java	2009-08-20 14:46:41 UTC (rev 92611)
@@ -1123,6 +1123,19 @@
    {
       try
       {
+         // Yes, ugly way of doing things. But, this is only way to be able to
+         // support this existing invokeCallback(BeanContext<?> beanContext...)
+         // API
+         if (beanContext instanceof EnterpriseBeanContext)
+         {
+            // the EnterpriseBeanContext is capable of caching the AOP interceptor
+            // instances and hence faster. So let's use that version of
+            // invokeCallback(EnterpriseBeanContext, Class)
+            EnterpriseBeanContext<?> enterpriseBeanContext = (EnterpriseBeanContext<?>) beanContext;
+            this.invokeCallback(enterpriseBeanContext, callbackAnnotationClass);
+            return;
+         }
+         
          // Do lifecycle callbacks
          List<Class<?>> lifecycleInterceptorClasses = beanContainer.getInterceptorRegistry().getLifecycleInterceptorClasses();
          Advisor advisor = getAdvisor();
@@ -1141,6 +1154,32 @@
       }
    }
    
+   /**
+    * Invokes the lifecycle callback(s) represented by <code>callbackAnnotationClass</code>
+    * through a (cached) AOP interceptor chain, on the bean context represented by 
+    * <code>enterpriseBeanContext</code>.
+    * 
+    * @param enterpriseBeanContext
+    * @param callbackAnnotationClass
+    */
+   protected void invokeCallback(EnterpriseBeanContext<?> enterpriseBeanContext, Class<? extends Annotation> callbackAnnotationClass)
+   {
+      try
+      {
+         Interceptor interceptors[] = enterpriseBeanContext.getLifecycleInterceptors(callbackAnnotationClass);
+         Constructor<?> constructor = beanClass.getConstructor();
+         Object initargs[] = null;
+         ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
+         invocation.setAdvisor(this.getAdvisor());
+         invocation.setTargetObject(enterpriseBeanContext.getInstance());
+         invocation.invokeNext();
+      }
+      catch(Throwable t)
+      {
+         throw new RuntimeException(t);
+      }
+   }
+   
    public void invokePostConstruct(BeanContext<?> beanContext)
    {
       // FIXME: This is a dirty hack to notify AS EJBTimerService about what's going on
@@ -1730,4 +1769,15 @@
          this.semaphore.release();
       }
    }
+   
+   /**
+    * Returns the lifecycle callback interceptors (javax.interceptor.Interceptors)
+    * that have been defined on the bean
+    *  
+    * @return
+    */
+   public List<Class<?>> getLifecycleInterceptorClasses()
+   {
+      return this.beanContainer.getInterceptorRegistry().getLifecycleInterceptorClasses();
+   }
 }

Added: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java	                        (rev 0)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java	2009-08-20 14:46:41 UTC (rev 92611)
@@ -0,0 +1,151 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbacks;
+
+/**
+ * EnterpriseBeanContext
+ *
+ * Represents a {@link BeanContext}  for an {@link EJBContainer}
+ * 
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public abstract class EnterpriseBeanContext<T extends EJBContainer> extends BaseContext<T>
+{
+
+   /**
+    * Maintains a array of interceptors applicable to this bean context
+    * for each of the lifecycle callbacks
+    */
+   protected transient Map<Class<? extends Annotation>, Interceptor[]> lifecycleCallbackInterceptors = new HashMap<Class<? extends Annotation>, Interceptor[]>();
+
+   /**
+    * 
+    * @param container Container instance associated with this bean
+    *                   context
+    */
+   protected EnterpriseBeanContext(T container)
+   {
+      super(container);
+   }
+
+   /**
+    * 
+    * @param container Container instance associated with this bean context
+    * @param bean The instance of the bean implementation
+    */
+   protected EnterpriseBeanContext(T container, Object bean)
+   {
+      super(container, bean);
+   }
+
+   /**
+    * Only for externalization use by subclass StatefulBeanContext; do not use elsewhere.
+    *
+    * @deprecated
+    */
+   protected EnterpriseBeanContext()
+   {
+
+   }
+
+   /**
+    * Returns the interceptor instances (which is a combination of our internal
+    * AOP interceptors and bean developer defined {@link javax.interceptor.Interceptors}),
+    * corresponding to the <code>lifecycleCallbackAnnotation</code>.
+    * 
+    * Internally caches the interceptor instances corresponding to each of the lifecycle 
+    * callbacks, for this bean context 
+    *  
+    * @param lifecycleCallbackAnnotation Lifecycle callback annotations like {@link PrePassivate},
+    *       {@link PostActivate}, {@link PreDestroy}, {@link PostConstruct} 
+    *       
+    * @return Returns an empty array if there are no interceptor instances associated with this
+    *       bean context, for the <code>lifecycleCallbackAnnotation</code>. Else, returns the
+    *       array of interceptors applicable to this bean context for the 
+    *       <code>lifecycleCallbackAnnotation</code>
+    */
+   public Interceptor[] getLifecycleInterceptors(Class<? extends Annotation> lifecycleCallbackAnnotation)
+   {
+      Interceptor[] interceptors = this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
+      // If null then we haven't yet initialized the lifecycle callback interceptors, since
+      // we intentionally do a lazy initialization per lifecycle callback. The initialization
+      // happens only once, when this method is called for the first time on this bean context,
+      // for the specific lifecycle callback annotation.
+      if (interceptors == null)
+      {
+         interceptors = this.createLifecycleInterceptors(lifecycleCallbackAnnotation);
+         if (interceptors == null)
+         {
+            // No interceptors available, so create an empty chain and maintain in the map,
+            // to avoid trying to init again the next time
+            // this method is called for this specifc lifecycle callback
+            interceptors = new Interceptor[0];
+         }
+         this.lifecycleCallbackInterceptors.put(lifecycleCallbackAnnotation, interceptors);
+      }
+      return this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
+   }
+
+   /**
+    * Creates an AOP interceptor chain out of the lifecycle interceptors for the
+    * <code>lifecycleCallbackAnnotation</code>
+    * 
+    * @param lifecycleCallbackAnnotation The lifecycle callback annotation
+    * @return
+    */
+   protected Interceptor[] createLifecycleInterceptors(Class<? extends Annotation> lifecycleCallbackAnnotation)
+   {
+      // Get the lifecycle interceptor classes of the bean 
+      List<Class<?>> lifecycleInterceptorClasses = this.getContainer().getLifecycleInterceptorClasses();
+      Advisor advisor = this.getContainer().getAdvisor();
+      Interceptor interceptors[];
+      try
+      {
+         // Create a AOP interceptor chain out of the lifecycle interceptor classes
+         interceptors = LifecycleCallbacks.createLifecycleCallbackInterceptors(advisor, lifecycleInterceptorClasses,
+               this, lifecycleCallbackAnnotation);
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Could not create lifecycle interceptor for lifecycle "
+               + lifecycleCallbackAnnotation + " on bean context " + this);
+      }
+
+      return interceptors;
+   }
+
+}

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java	2009-08-20 12:55:24 UTC (rev 92610)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java	2009-08-20 14:46:41 UTC (rev 92611)
@@ -23,7 +23,7 @@
 
 import javax.ejb.EJBContext;
 
-import org.jboss.ejb3.BaseContext;
+import org.jboss.ejb3.EnterpriseBeanContext;
 
 /**
  * Comment
@@ -31,7 +31,7 @@
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
  * @version $Revision$
  */
-public class MDBContext extends BaseContext<MessagingContainer>
+public class MDBContext extends EnterpriseBeanContext<MessagingContainer>
 {
    protected EJBContext ejbContext;
 

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java	2009-08-20 12:55:24 UTC (rev 92610)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java	2009-08-20 14:46:41 UTC (rev 92611)
@@ -23,7 +23,7 @@
 
 import javax.ejb.EJBContext;
 
-import org.jboss.ejb3.BaseContext;
+import org.jboss.ejb3.EnterpriseBeanContext;
 
 /**
  * An instance of an enterprise bean link to its container.
@@ -31,7 +31,7 @@
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
  * @version $Revision$
  */
-public abstract class SessionBeanContext<T extends SessionContainer> extends BaseContext<T>
+public abstract class SessionBeanContext<T extends SessionContainer> extends EnterpriseBeanContext<T>
 {
    protected EJBContext ejbContext;
 




More information about the jboss-cvs-commits mailing list