190 likes | 285 Views
Dynamic Proxies in Java And so on into winter Till even I have ceased To come as a foot printer, And only some slight beast So mousy or foxy Shall print there as my proxy. Robert Frost “Closed for Good”. Joe Dane jdane@hawaii.edu April 28, 2004. What’s a Proxy?.
E N D
Dynamic Proxies in JavaAnd so on into winterTill even I have ceasedTo come as a foot printer,And only some slight beastSo mousy or foxyShall print there as my proxy.Robert Frost “Closed for Good” Joe Dane jdane@hawaii.edu April 28, 2004
What’s a Proxy? • “The agency for another who acts through the agent; authority to act for another” (Webster) • “Provide a surrogate or placeholder for another object to control access to it” (GoF) • Types of proxies mentioned: • remote • “virtual” (e.g. loading on demand) • protection • “smart references” • e.g. ref counting, locking, etc.
“static” proxies implements “real” server uses Forwards to Interface Client implements Proxy By way of Factory Generates or obtains
General Proxy comments • Using static proxies means tracking changes in interfaces, writing dummy methodsm recompiling. • Also implies that we can’t use a framework that doesn’t know about our interfaces. • Can’t use a Constructor • GoF doesn’t mention this • Must use a factory or registry
Dynamic What? • “Proxy”, because we create an object to “stand in” for another object • “Dynamic” because the object is defined at runtime. • Means we must have JVM support. • Bottom line: at runtime, create objects which wrap other objects (services) and add functionality.
Why proxies? • Enhance services w/o changing either clients or servers • If you need to look at the method, you probably don’t want a D.P. • Explicit control over method invocation. • No need to explicitly implement all methods in an interface. • You’re probably already using them. • App servers, Axis, hibernate
Some Examples Logging, failover “Memoization” XML data binding Enforce security restrictions Transaction management
Our model • Services • Interfaces which define behaviors • Servers • Programs which provide (implement) one or more services • Clients • Obtain references to services (cf factory pattern) • No knowledge of server details • Services may be local or remote
Digression: Reflection Basics • java.lang.reflect package • Classes which represent the basic units of Java. • Class, Method, Constructor • From a Class, we can get a Method. • From a Method, we can ‘invoke’ on an object and arguments. • object.methodname(arg1, arg2, …) • method.invoke(object, args[]) • Syntax: Foo.class
Creating a proxy • Things you need • A ClassLoader • An array of interfaces to implement • An InvocationHandler • What’s the InvocationHandler? • Basically, a single method. Could do anything • Doesn’t usually implement any essential business logic • Dispatches to an underlying service, possibly after (or before) providing some additional service. • Note: underlying service may itself be a proxy!
Creating a proxy (short) TheInterface object = (TheInterface) Proxy.newProxyInstance( TheInterface.class.getClassLoader(), new Class[] { TheInterface.class }, new SimpleHandler() );
Creating a proxy (long) try { Class proxyClass = Proxy.getProxyClass( TheInterface.class.getClassLoader(), new Class[] { TheInterface.class } ); Constructor constructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class }); InvocationHandler handler = new SimpleHandler(); TheInterface object = (TheInterface) constructor.newInstance(new Object[] { handler }); } catch (Exception e) { … }
Proxy Properties • Can be cast to any interface used in creating the proxy class. • instanceof works as expected • Proxy.isProxyClass() is true for the class • Class name is undetermined, but will probably be something like Proxy$1. • Method invocation is encoded and dispatched to the handler’s invoke method. • Is Serializable • This is huge! • Implications for RMI, JNDI, J2EE
Simple proxy use Client Factory Get proxy reference Proxy handler Service Service Service
Advanced proxy use Client P3 P1 P2 Service
Downsides • Loss of static guarantees • Can make code difficult to understand • Can’t proxy classes, only interfaces • Slow? • Requires JDK 1.3 • All invocations go through the handler, even toString, equals(), etc., which were not in any interface. • The creation syntax is ugly.
Upsides • Proxy handlers don’t have to be updated when service interfaces change. • SOC: We can add behavior w/o changing servers or clients. • Serializable means we can store proxies anywhere we like. • c.f. App Servers: WebLogic, JBOSS, etc. • Slow? Not really.
Proxy examples • Simple example • Simple (but slightly more realistic) example • Logging and profiling method calls • A “memoizing” handler • Load balancing and fail-over • Some timing examples • A “real world” example, time permitting
References • java.lang.reflect API docs • Sun’s web page describing dynamic proxies. Contains simple examples and one more complicated example. Good starting point. • http://java.sun.com/j2ee/1.3/docs/guide/reflection/proxy.html • Post to RMI-USERS mailing list describing how to use dynamic proxies to eliminate the need for rmic. Mind bending, not for the faint hearted. • http://swjscmail.java.sun.com/cgi-bin/wa?A2=ind0009&L=rmi-users&P=R3631 • Related projects: cglib, BCEL, AoP