Java Reflection in Action: Using Java's Dynamic Proxy | WebReference

Java Reflection in Action: Using Java's Dynamic Proxy

Java Reflection in Action: Using Java's Dynamic Proxy

Written by Ira R. Forman and Nate Forman and reproduced from "Java Reflection in Action" by permission of Manning Publications Co. ISBN 1932394184, copyright 2004. All rights reserved. See http://www.manning.com for more information.

In this excerpt, you'll notice discussions about "George," a fictional programmer who tackles common but difficult tasks throughout the book. He was introduced earlier in the book, so seeing him appear here might seem a bit unusual. [Ed.]

In this chapter

The dictionary [68] tells us that a proxy is an "agency, function, or office of a deputy who acts as a substitute for another." When this idea is applied to object-oriented programming, the result is an object, a proxy, that supports the interface of another object, its target, so that the proxy can substitute for the target for all practical purposes.

The keys to this arrangement are implementation and delegation. The proxy implements the same interface as the target so that it can be used in exactly the same way. The proxy delegates some or all of the calls that it receives to its target and thus acts as either an intermediary or a substitute. In its role as an intermediary, the proxy may add functionality either before or after the method is forwarded to the target. This gives the reflective programmer the capability to add behavior to objects. This chapter discusses this and other uses of proxies.

4.1 Working with proxies

The sequence diagram in figure 4.1 depicts the most common situation where the proxy instance receives a method call and forwards it to the target. Even this arrangement has a use; it hides the location of the target from the client. If you have used remote method invocation, you are familiar with proxies that are local substitutes for remote objects.

The Java reflection API contains a dynamic proxy-creation facility, java.lang.reflect.Proxy. This class is part of Java reflection because Proxy is Java's only way of approximating method invocation intercession. Let's dissect the previous phrase. Intercession is any reflective ability that modifies the behavior of a program by directly taking control of that behavior. Method invocation intercession is the ability to intercept method calls. The intercepting code can determine the behavior that results from the method call.

We say approximating because Java does not support reflective facilities for interceding on method calls. Therefore, we must use proxies as an approximation. Referring to figure 4.1, we see that proxies also allow the ability to pre- and postprocess method calls. Let's examine the benefits achieved from doing this.

Programmers commonly discuss properties of classes. For example, a class that records its method calls is often referred to as a tracing class. A class that ensures that a failed operation does not leave an object in an intermediate state is often referred to as an atomic class.

The code that implements such properties is usually spread among the definitions of each of the methods of the class, almost always at the beginning and at the return points. The ability to intercede on method invocation permits the

programmer to gather this property-implementing code together in one place. This property can later combine with classes, yielding the desired effect.

The case for this combination of classes and properties is more real for software projects than you would think. A colleague once observed that when an object-oriented database is first brought into a programming shop, the number of classes doubles. The shop has added one property, persistence, to their application. Each class now requires a persistent and a nonpersistent version [18].

Developers get many key benefits from separating property-implementing code. One benefit of this separation is low maintenance cost for applications. Each such property can be modified by making a change in only one place in the code base. Another benefit of separating properties is improved reusability. The separated property can be used in many places in many applications.

There is also a compelling argument to present to management for such separation. Consider George's employer, Wildlife Components, which sells a class library of n classes. There are p properties that they wish their classes to have in all combinations. Both the number of classes and the number of properties grow as the company evolves to meet the increasing business demands. WCI faces the possibility of having to support a class library of at least n2p classes if they must write new classes to implement and combine properties in their original classes.

This additional maintenance is a serious enough concern to win management over. Isolating properties into reusable components and composing them later, as can be done with Proxy, yields a much smaller library of size n+p. This represents an enormous savings to WCI or any other company. This effect may not be as pronounced in other organizations, but it does exist.

Now that we have discussed the abstract benefits of Proxy, let's pay a visit to George and look at a simple example.


Created: March 27, 2003
Revised: November 12, 2004

URL: http://webreference.com/internet/reflection/1