What are dynamic proxy classes and why should I use it?

What is the use of a dynamic proxy?

How do they relate to the generation and reflection of bytecode?

Any recommended reading?

+56
java design-patterns dynamic-proxy
Jun 01 '09 at 8:39
source share
5 answers

I highly recommend this resource.

First of all, you should understand what is used to use the proxy template. Remember that the main purpose of the proxy server is to control access to the target, and not to increase the functionality of the target. Access control includes synchronization, authentication, remote access (RPC), lazy instance (Hibernate, Mybatis), AOP (transaction).

Unlike a static proxy, a dynamic proxy generates bytecode that requires Java reflection at runtime. With dynamics, you donโ€™t need to put a proxy class, which can lead to more convenience.

+13
Jan 26 '14 at 1:57
source share

A dynamic proxy class is a class that implements a list of interfaces specified at runtime, so a method call through one of the interfaces on an instance of the class will be encoded and sent to another object through a single interface. It can be used to create a protected type of proxy object for a list of interfaces without requiring pre-generation of a proxy class. Dynamic proxy classes are useful for applications or libraries that need to provide type-safe reflective calls to objects that have an API interface.

Dynamic proxy classes

+28
Jun 01 '09 at 8:55
source share

I just came up with an interesting use for dynamic proxy.

We had some problems with a non-critical service that is associated with another dependent service and wanted to learn how to failover when this dependent service becomes unavailable.

So, I wrote a LoadSheddingProxy that accepts two delegates - one of them is a remote call for a "normal" service (after searching for JNDI). Another object is the 'dummy' load-shedding impl. There is simple logic surrounding every invoke method, which catches timeouts and redirects to fictions for a certain period of time before retrying. Here is how I use it:

// This is part of your ServiceLocator class public static MyServiceInterface getMyService() throws Exception { MyServiceInterface loadShedder = new MyServiceInterface() { public Thingy[] getThingys(Stuff[] whatever) throws Exception { return new Thingy[0]; } //... etc - basically a dummy version of your service goes here } Context ctx = JndiUtil.getJNDIContext(MY_CLUSTER); try { MyServiceInterface impl = ((MyServiceHome) PortableRemoteObject.narrow( ctx.lookup(MyServiceHome.JNDI_NAME), MyServiceHome.class)).create(); // Here where the proxy comes in return (MyService) Proxy.newProxyInstance( MyServiceHome.class.getClassLoader(), new Class[] { MyServiceInterface.class }, new LoadSheddingProxy(MyServiceHome.JNDI_NAME, impl, loadShedder, 60000)); // 10 minute retry } catch (RemoteException e) { // If we can't even look up the service we can fail by shedding load too logger.warn("Shedding load"); return loadShedder; } finally { if (ctx != null) { ctx.close(); } } } 

And here is the proxy:

 public class LoadSheddingProxy implements InvocationHandler { static final Logger logger = ApplicationLogger.getLogger(LoadSheddingProxy.class); Object primaryImpl, loadDumpingImpl; long retry; String serviceName; // map is static because we may have many instances of a proxy around repeatedly looked-up remote objects static final Map<String, Long> servicesLastTimedOut = new HashMap<String, Long>(); public LoadSheddingProxy(String serviceName, Object primaryImpl, Object loadDumpingImpl, long retry) { this.serviceName = serviceName; this.primaryImpl = primaryImpl; this.loadDumpingImpl = loadDumpingImpl; this.retry = retry; } public Object invoke(Object obj, Method m, Object[] args) throws Throwable { try { if (!servicesLastTimedOut.containsKey(serviceName) || timeToRetry()) { Object ret = m.invoke(primaryImpl, args); servicesLastTimedOut.remove(serviceName); return ret; } return m.invoke(loadDumpingImpl, args); } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); // DETECT TIMEOUT HERE SOMEHOW - not sure this is the way to do it??? if (targetException instanceof RemoteException) { servicesLastTimedOut.put(serviceName, Long.valueOf(System.currentTimeMillis())); } throw targetException; } } private boolean timeToRetry() { long lastFailedAt = servicesLastTimedOut.get(serviceName).longValue(); return (System.currentTimeMillis() - lastFailedAt) > retry; } } 
+16
Nov 18 '09 at 15:11
source share

The java.lang.reflect.Proxy class allows you to dynamically implement interfaces by processing method calls in the InvocationHandler . It is considered part of the Java reflection tool, but has nothing to do with bytecode generation.

Sun tutorial on using the proxy class. Google also helps.

+8
Jun 01 '09 at 8:46
source share

One use case is hibernation - it provides you with objects that implement the model classes interface, but when using getters and seters, there is code associated with db. That is, you use them as if they were just POJO, but in fact a lot of things are happening undercover.

For example, you simply call the recipient of a lazily loaded property, but in fact the property (possibly the whole large structure of the object) is retrieved from the database.

For more information you should check cglib .

+5
Jun 01 '09 at 8:47
source share



All Articles