A high-performance factory for dynamic proxy objects : Proxy « Reflection « Java






A high-performance factory for dynamic proxy objects

  
/*
 * Copyright 2006 (C) TJDO.
 * All rights reserved.
 *
 * This software is distributed under the terms of the TJDO License version 1.0.
 * See the terms of the TJDO License in the documentation provided with this software.
 *
 * $Id: ProxyFactory.java,v 1.1 2006/08/11 20:41:59 jackknifebarber Exp $
 */


import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;


/**
 * A high-performance factory for dynamic proxy objects.
 * <p>
 * A ProxyFactory performs the same function as
 * <tt>java.lang.reflect.Proxy.newProxyInstance()</tt>, but does so for a single
 * set of interfaces.
 * It holds a (soft) reference to the proxy class constructor and so can create
 * many proxies of the same type with very little overhead.
 * <p>
 * The generated proxy class is assigned the same class loader as the
 * <tt>ProxyFactory</tt> class itself.
 *
 * @author <a href="mailto:jackknifebarber@users.sourceforge.net">Mike Martin</a>
 * @version $Revision: 1.1 $
 */

public class ProxyFactory
{
    private final Class[] interfaces;
    private Reference ctorRef;


    /**
     * Creates a factory for proxy objects that implement the specified
     * interface.
     *
     * @param intfc
     *      the interface for the proxy class to implement
     */
    public ProxyFactory(Class intfc)
    {
        this(new Class[] { intfc });
    }

    /**
     * Creates a factory for proxy objects that implement the specified
     * interface(s).
     *
     * @param interfaces
     *      the list of interfaces for the proxy class to implement
     */
    public ProxyFactory(Class[] interfaces)
    {
        this.interfaces = interfaces;
    }

    /**
     * Returns an instance of a proxy class for this factory's interfaces that
     * dispatches method invocations to the specified invocation handler. 
     * <tt>ProxyFactory.newInstance</tt> throws <tt>IllegalArgumentException</tt>
     * for the same reasons that <tt>Proxy.getProxyClass</tt> does.
     *
     * @param handler
     *      the invocation handler to dispatch method invocations to 
     * @return
     *      a proxy instance with the specified invocation handler of a proxy
     *      class that implements this factory's specified interfaces 
     *
     * @throws IllegalArgumentException
     *      if any of the restrictions on the parameters that may be passed to
     *      <tt>getProxyClass</tt> are violated 
     * @throws NullPointerException
     *      if the invocation handler is null
     */
    public Object newInstance(InvocationHandler handler)
    {
        if (handler == null)
            throw new NullPointerException();

        try
        {
            return getConstructor().newInstance(new Object[] { handler });
        }
        catch (InstantiationException e)    { throw new InternalError(e.toString()); }
        catch (IllegalAccessException e)    { throw new InternalError(e.toString()); }
        catch (InvocationTargetException e) { throw new InternalError(e.toString()); }
    }

    private synchronized Constructor getConstructor()
    {
        Constructor ctor = ctorRef == null ? null : (Constructor)ctorRef.get();

        if (ctor == null)
        {
            try
            {
                ctor = Proxy.getProxyClass(getClass().getClassLoader(), interfaces)
                            .getConstructor(new Class[] { InvocationHandler.class });
            }
            catch (NoSuchMethodException e)
            {
                throw new InternalError(e.toString());
            }

            ctorRef = new SoftReference(ctor);
        }

        return ctor;
    }
}

   
    
  








Related examples in the same category

1.A demonstration of a proxy factory
2.Demonstrates the basic concept of proxies generated by clients to the proxies
3.Demonstrates a dangerous use of proxy names
4.Creating a Proxy Object
5.A dynamic proxy adapter which allows overriding several methods of a target proxy
6.This program demonstrates the use of proxies and reflection