Andreas,

Would you mind to update the dev list (or one of the JIRA issue) about
the design in your mind for this implementation ?

Thanks !

On Wed, Sep 7, 2011 at 5:11 PM,  <veit...@apache.org> wrote:
> Author: veithen
> Date: Wed Sep  7 11:41:52 2011
> New Revision: 1166132
>
> URL: http://svn.apache.org/viewvc?rev=1166132&view=rev
> Log:
> AXIS2-4524 / AXIS2-4878 / AXIS2-5118 / AXIS2-5119: Initial implementation of 
> a BeanInfo cache to speed up POJO services.
>
> Added:
>    
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java
>    (with props)
>    
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java
>    (with props)
> Modified:
>    
> axis/axis2/java/core/trunk/modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java
>    
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/DeploymentClassLoader.java
>
> Modified: 
> axis/axis2/java/core/trunk/modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java
> URL: 
> http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java?rev=1166132&r1=1166131&r2=1166132&view=diff
> ==============================================================================
> --- 
> axis/axis2/java/core/trunk/modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java
>  (original)
> +++ 
> axis/axis2/java/core/trunk/modules/adb/src/org/apache/axis2/databinding/utils/BeanUtil.java
>  Wed Sep  7 11:41:52 2011
> @@ -22,7 +22,6 @@ package org.apache.axis2.databinding.uti
>
>  import java.beans.BeanInfo;
>  import java.beans.IntrospectionException;
> -import java.beans.Introspector;
>  import java.beans.PropertyDescriptor;
>  import java.lang.reflect.Array;
>  import java.lang.reflect.InvocationTargetException;
> @@ -58,6 +57,7 @@ import org.apache.axiom.om.impl.dom.DOOM
>  import org.apache.axiom.om.impl.dom.DocumentImpl;
>  import org.apache.axiom.om.util.Base64;
>  import org.apache.axis2.AxisFault;
> +import org.apache.axis2.classloader.BeanInfoCache;
>  import org.apache.axis2.context.MessageContext;
>  import org.apache.axis2.databinding.typemapping.SimpleTypeMapper;
>  import org.apache.axis2.databinding.utils.reader.ADBXMLStreamReaderImpl;
> @@ -121,19 +121,7 @@ public class BeanUtil {
>
>
>     private static BeanInfo getBeanInfo(Class beanClass, Class 
> beanSuperclass) throws IntrospectionException {
> -        BeanInfo beanInfo;
> -        try {
> -            if (beanSuperclass != null)
> -               beanInfo = Introspector.getBeanInfo(beanClass, 
> beanSuperclass);
> -            else
> -                beanInfo = Introspector.getBeanInfo(beanClass);
> -        }
> -        catch (IntrospectionException e) {
> -            throw e;
> -        }
> -
> -
> -        return beanInfo;
> +        return BeanInfoCache.getCachedBeanInfo(beanClass, beanSuperclass);
>     }
>
>     private static BeanInfo getBeanInfo(Class beanClass) throws 
> IntrospectionException {
>
> Added: 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java
> URL: 
> http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java?rev=1166132&view=auto
> ==============================================================================
> --- 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java
>  (added)
> +++ 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java
>  Wed Sep  7 11:41:52 2011
> @@ -0,0 +1,130 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.axis2.classloader;
> +
> +import java.beans.BeanInfo;
> +import java.beans.IntrospectionException;
> +import java.beans.Introspector;
> +import java.util.Map;
> +import java.util.concurrent.ConcurrentHashMap;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +/**
> + * {@link BeanInfo} cache that stores introspection results by bean class 
> and stop class. This goes
> + * beyond the caching provided by the JRE, which only caches the results of
> + * {@link Introspector#getBeanInfo(Class)}, but not the results of
> + * {@link Introspector#getBeanInfo(Class, Class)} (with non null stop class).
> + * <p>
> + * To avoid class loader leaks, this class should not be used as a singleton 
> if the introspected
> + * classes are loaded from class loaders that are children of the class 
> loader which holds the
> + * reference to the cache. In such scenarios, use {@link 
> #getCachedBeanInfo(Class, Class)}.
> + */
> +public final class BeanInfoCache {
> +    private static final class CacheKey {
> +        private final Class<?> beanClass;
> +        private final Class<?> stopClass;
> +
> +        CacheKey(Class<?> beanClass, Class<?> stopClass) {
> +            this.beanClass = beanClass;
> +            this.stopClass = stopClass;
> +        }
> +
> +        @Override
> +        public int hashCode() {
> +            return 31*beanClass.hashCode() + (stopClass == null ? 0 : 
> stopClass.hashCode());
> +        }
> +
> +        @Override
> +        public boolean equals(Object obj) {
> +            if (obj instanceof CacheKey) {
> +                CacheKey other = (CacheKey)obj;
> +                return beanClass == other.beanClass && stopClass == 
> other.stopClass;
> +            } else {
> +                return false;
> +            }
> +        }
> +    }
> +
> +    private static final Log log = LogFactory.getLog(BeanInfoCache.class);
> +
> +    /**
> +     * Local cache instance for Javabeans that are loaded from the same 
> class loader as this class.
> +     */
> +    private static final BeanInfoCache localCache = new BeanInfoCache();
> +
> +    private final Map<CacheKey,BeanInfo> cache = new 
> ConcurrentHashMap<CacheKey,BeanInfo>();
> +
> +    /**
> +     * Introspect on a Java bean and return a cached {@link BeanInfo} object.
> +     *
> +     * @param beanClass
> +     *            The bean class to be analyzed.
> +     * @param stopClass
> +     *            The base class at which to stop the analysis; may be 
> <code>null</code>.
> +     * @return A {@link BeanInfo} object describing the target bean.
> +     * @exception IntrospectionException
> +     *                if an exception occurs during introspection.
> +     * @see Introspector#getBeanInfo(Class, Class)
> +     */
> +    public BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass) 
> throws IntrospectionException {
> +        CacheKey key = new CacheKey(beanClass, stopClass);
> +        BeanInfo beanInfo = cache.get(key);
> +        if (beanInfo == null) {
> +            beanInfo = Introspector.getBeanInfo(beanClass, stopClass);
> +            cache.put(key, beanInfo);
> +        }
> +        return beanInfo;
> +    }
> +
> +    /**
> +     * Locate an appropriate {@link BeanInfoCache} and return a cached 
> {@link BeanInfo} object.
> +     * This method ensures that caching the {@link BeanInfo} object will not 
> result in a class
> +     * loader leak.
> +     *
> +     * @param beanClass
> +     *            The bean class to be analyzed.
> +     * @param stopClass
> +     *            The base class at which to stop the analysis; may be 
> <code>null</code>.
> +     * @return A {@link BeanInfo} object describing the target bean.
> +     * @exception IntrospectionException
> +     *                if an exception occurs during introspection.
> +     */
> +    public static BeanInfo getCachedBeanInfo(Class<?> beanClass, Class<?> 
> stopClass) throws IntrospectionException {
> +        ClassLoader classLoader = beanClass.getClassLoader();
> +        BeanInfoCache cache;
> +        if (classLoader instanceof BeanInfoCachingClassLoader) {
> +            cache = 
> ((BeanInfoCachingClassLoader)classLoader).getBeanInfoCache();
> +        } else if (classLoader == BeanInfoCache.class.getClassLoader()) {
> +            cache = localCache;
> +        } else {
> +            cache = null;
> +        }
> +        if (cache != null) {
> +            return cache.getBeanInfo(beanClass, stopClass);
> +        } else {
> +            if (log.isWarnEnabled()) {
> +                log.warn("Unable to locate a BeanInfo cache for " + 
> beanClass + " (stopClass=" + stopClass
> +                        + "). This will negatively affect performance!");
> +            }
> +            return Introspector.getBeanInfo(beanClass, stopClass);
> +        }
> +    }
> +}
>
> Propchange: 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCache.java
> ------------------------------------------------------------------------------
>    svn:eol-style = native
>
> Added: 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java
> URL: 
> http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java?rev=1166132&view=auto
> ==============================================================================
> --- 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java
>  (added)
> +++ 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java
>  Wed Sep  7 11:41:52 2011
> @@ -0,0 +1,33 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.axis2.classloader;
> +
> +import java.beans.BeanInfo;
> +
> +/**
> + * Interface implemented by class loaders that keep a {@link BeanInfo} cache.
> + */
> +public interface BeanInfoCachingClassLoader {
> +    /**
> +     * Get the {@link BeanInfo} cache for this class loader.
> +     *
> +     * @return the cache instance; must not be <code>null</code>
> +     */
> +    BeanInfoCache getBeanInfoCache();
> +}
>
> Propchange: 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/classloader/BeanInfoCachingClassLoader.java
> ------------------------------------------------------------------------------
>    svn:eol-style = native
>
> Modified: 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/DeploymentClassLoader.java
> URL: 
> http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/DeploymentClassLoader.java?rev=1166132&r1=1166131&r2=1166132&view=diff
> ==============================================================================
> --- 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/DeploymentClassLoader.java
>  (original)
> +++ 
> axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/DeploymentClassLoader.java
>  Wed Sep  7 11:41:52 2011
> @@ -20,6 +20,8 @@
>  package org.apache.axis2.deployment;
>
>  import org.apache.axiom.attachments.utils.IOUtils;
> +import org.apache.axis2.classloader.BeanInfoCache;
> +import org.apache.axis2.classloader.BeanInfoCachingClassLoader;
>
>  import java.io.ByteArrayInputStream;
>  import java.io.IOException;
> @@ -36,7 +38,7 @@ import java.util.List;
>  import java.util.zip.ZipEntry;
>  import java.util.zip.ZipInputStream;
>
> -public class DeploymentClassLoader extends URLClassLoader {
> +public class DeploymentClassLoader extends URLClassLoader implements 
> BeanInfoCachingClassLoader {
>     // List of URL's
>     private URL[] urls = null;
>
> @@ -45,6 +47,8 @@ public class DeploymentClassLoader exten
>
>     private boolean isChildFirstClassLoading;
>
> +    private final BeanInfoCache beanInfoCache = new BeanInfoCache();
> +
>     /**
>      * DeploymentClassLoader is extended from URLClassLoader. The constructor
>      * does not override the super constructor, but takes in an addition list 
> of
> @@ -291,4 +295,8 @@ public class DeploymentClassLoader exten
>     public void setChildFirstClassLoading(boolean childFirstClassLoading) {
>         isChildFirstClassLoading = childFirstClassLoading;
>     }
> +
> +    public final BeanInfoCache getBeanInfoCache() {
> +        return beanInfoCache;
> +    }
>  }
>
>
>



-- 
Sagara Gunathunga

Blog      - http://ssagara.blogspot.com
Web      - http://people.apache.org/~sagara/
LinkedIn - http://www.linkedin.com/in/ssagara

---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscr...@axis.apache.org
For additional commands, e-mail: java-dev-h...@axis.apache.org

Reply via email to