Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Java Dynamic Proxies: One Step from Aspect-oriented Programming : Page 3

Learn how to implement application concerns such as logging and remote error handling across classes using dynamic proxies. Along the way, you'll find out what dynamic proxies and aspect-oriented programming (AOP) have in common.


WEBINAR: On-demand Event

Unleash Your DevOps Strategy by Synchronizing Application and Database Changes REGISTER >

Remote Proxies
The simple Logging example in the previous section indicates how easily you can incorporate more sophisticated logic such as performance diagnostics, metric collection, and result caching into your code. However, that is just the start. For distributed applications, proxies open up more interesting possibilities.

One of the major concerns of distributed computing is the management of client/server communication. Typically, the responsibility for managing low-level communication falls to the client code. Business-level functions can get mixed in with low-level networking, error handling, and retry code, which increases coupling and makes your code messy and hard to maintain. One way to handle this is to centralize the networking aspects of your system inside remote proxies or business delegates (Marinescu). From the client's perspective, the proxy appears just like a normal class. Any problems communicating with the backend are hidden, and network-related errors such as RemoteExceptions or EJBExceptions get translated into something more meaningful to the client.

Remote proxies are useful but extremely tedious to write if you have to create them for every single Remote or EJB interface. Dynamic proxies can alleviate the problem by providing a common, type-safe component for mediating client/server communication. The first step is to ensure that your code for locating remote services is centralized. This can be a simple factory class or more likely a ServiceLocator class. Locator classes hide the complexity of discovering and creating server-related artifacts. You can either add your dynamic proxy to your existing ServiceLocator or create a new Factory/Locator that wraps the old one. Here's a simple ServiceLocator class that returns a proxy instead of an EJB instance:

public final class ServiceLocator { /** * Locate a Remote service **/ public static Object locate(Class classInterface) throws NetworkException { // Create Handler InvocationHandler handler = new RemoteProxyHandler(classInterface); // Create Remote Proxy Object proxy = Proxy.newProxyInstance(classInterface.getClassLoader(), new Class[] { classInterface}, handler); return proxy; } }

When a method is executed on the proxy, it is the RemoteProxyHandler's responsibility to manage the EJB specifics: EJBHome location, EJB creation, and remote method execution. This way, the client is totally shielded from the complications of using a remote service:

public class RemoteProxyHandler implements InvocationHandler { public static final int RETRY_LIMIT = 3; ... public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // find home if (home == null) { home = findHome(classInterface); } // create ejb if (bean == null) { bean = createEjb(home); } // invoke method Object result = invokeRemoteMethod(method, args); return result; }

You can add common error handling and retry semantics to all remote calls transparently:

protected Object invokeRemoteMethod(Method method, Object[] args) throws ApplicationException { int trys = 1; while (trys <= RETRY_LIMIT) { try { return method.invoke(bean, args); } catch (IllegalAccessException ie) { throw new ApplicationException(ie); } catch (InvocationTargetException e) { if (trys < RETRY_LIMIT) { ++trys; } else { throw new ApplicationException(e.getTargetException()); } //fi } //end catch } //end while return null; }

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date