Powered by Blogger.

Techniques for generating proxies dynamically in Java

A proxy object acts as an intermediary between a client object and target object. Lets discuss here the techniques for generating proxies dynamically in Java and advantages of doing so.

MediaPlayer example with no proxy:
i) Client object interacts with a target object directly:



WinPlayer class implements the IMediaPlayer interface



ClientObject1 interacts with a WinPlayer Media Player directly


Output for Media Player example with no proxy:

Win Player started playing Sleep Away...
Win Player stopped playing Sleep Away...

MediaPlayer example with proxy:
ii) Client object  interacts with a target object through a proxy:

The main purpose of a proxy is to control access to the Win Player Media Player/ target object, rather than to enhance the functionality of it.

Here is our Media Player proxy:


ClientObject2 interacts with a WinPlayer Media Player through a proxy

Output:
MediaPlayerProxy: Begin of Playing song
Win Player started playing Sleep Away...
MediaPlayerProxy: End of Playing song

Dynamic Proxies in Java:
  • Java 1.3 supports the creation of dynamic proxy classes and instances
  • Dynamic proxy class -> class that implements a list of interfaces specified at runtime when the class is created.
  • Proxy interface -> interface that is implemented by proxy class
  • Proxy instance -> instance of the proxy class
  • Each proxy instance has an associated invocation handler object
  • Invocation handler object implements the interface InvocationHandler
  • Proxy classes created through new java.lang.reflect.Proxy class
  • Proxy classes are public, final, non-abstract subclasses of java.lang.reflect.Proxy class
  • Each Proxy class has one public constructor with one argument, an implementation of the interface InvocationHandler, to set the invocation handler for a proxy instance.
  • Rather than having to use the Reflection API to access the public constructor, a proxy instance can also be created by calling the Proxy.newInstance() method
iii) ClientObject3 interacts with WinPlayer Media Player/ target object through a dynamically generated MediaPlayerproxy


Output:
Media Player Handler: Invokingstart
Win Player started playing Sleep Away...
Media Player Handler: Invokingstop
Win Player stopped playing Sleep Away...

Benefit of dynamically generating the proxy:
  • We still had to write the invocation handler class!
  • Now there is another object layer between the client object and the target object.
Where we should use dynamic proxies ?
  • Generic delegation
  • Dynamic generation of proxies (stubs) for remote objects
Generic Delegation:

To explain generic delegation let us try to add logging capability to our MediaPlayer example. Suppose that we want to log each action (start, stop etc.,) that we perform on WinPlayer, but we dont want to modify the existing WinPlayer code. Sounds like the job of Decorator pattern. 

iv) Client object interacts with target object through a logging Decorator:
Output:
Log Entry : Win Player started playingSleep Away...
Win Player started playing Sleep Away...
Log Entry : Win Player stoped playingSleep Away...
Win Player stopped playing Sleep Away...

Difference between Proxy Pattern and Decorator Pattern:

Proxy provides access control, While Decorator adds functionality, in this case a logging capability. So LoggedMediaPlayer Decorator class provides a logging capability for any class that implements IMediaPlayer

Drawbacks of this approach:
  • It is not good to implement all of the methods of IMediaPlayer interface in LoggedMediaPlayer class.
  • Logging is the generic functionality....
To overcome this drawback we can use dynamic proxies

v ) Client object interacts with target object through a dynamically generated proxy:

Generic Logger Generic Delegation Example using Dynamic Proxies:


Output:
Generic Logger Entry: Invokingstart
Win Player started playing Sleep Away...
Generic Logger Entry: Invokingstop
Win Player stopped playing Sleep Away...

The great thing about this generic logger is that it can be used to add a logging capability to any interface.

0 comments:

Post a Comment