Java tutorial
/* * 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; } }