Archief - JAVA: dynamic proxies

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

forloRn_

Legacy Member
Goeienacht,

Hieronder een typisch voorbeeld van het Proxy design pattern, maar dan met behulp van dynamic proxies. In het kort: de interface is Dao, de implementatie van die interface is DaoImpl, de dynamic proxy en de InvocationHandler CachingHandler onderscheppen calls naar de implementatie.

Tot zover alles okee, en het onderstaande werkt. Wat niet werkt, is de proxy instance uitprinten in de invoke() method van de InvocationHandler, dan krijg je namelijk een StackOverflowError. Bij nader inzien redelijk logisch: in invoke() onderschept de proxy opnieuw de call naar de implementatie, en komt weer in de invoke() method terecht, en opnieuw, en opnieuw, en opnieuw.

proxy.getClass() doen zoals hieronder werkt dus wel. Vraag: waarom wordt toString() onderschept en getClass() niet?

Code:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


interface Dao {
	void insert();
	void get();
	void update();
	void delete();
}

class DaoImpl implements Dao {
	public void insert() { System.out.println(this.getClass().getName() + ".insert()"); }
	public void get() { System.out.println(this.getClass().getName() + ".get()"); }
	public void update() { System.out.println(this.getClass().getName() + ".update()"); }
	public void delete() { System.out.println(this.getClass().getName() + ".delete()"); }
}

class CachingHandler implements InvocationHandler {
	
	private final Dao dao;
	
	public CachingHandler(Dao dao) {
		this.dao = dao;
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		// StackOverflowError
		// System.out.println(proxy);
		
		System.out.println(proxy.getClass().getName() + " intercepted " + method);
		
		return method.invoke(dao, args);
	}	
}

public class DynamicProxy {
	
	public static void f(Dao dao) {
		dao.insert();
		dao.get();
		dao.update();
		dao.delete();
	}

	public static void main(String[] args) {
		
		Dao dao = new DaoImpl();
		
		f(dao);
		
		Dao proxy = (Dao)Proxy.newProxyInstance(dao.getClass().getClassLoader(),
				new Class<?>[] { Dao.class },
				new CachingHandler(dao));
		
		f(proxy);
	}

}

Output:
Code:
DaoImpl.insert()
DaoImpl.get()
DaoImpl.update()
DaoImpl.delete()
$Proxy0 intercepted public abstract void Dao.insert()
DaoImpl.insert()
$Proxy0 intercepted public abstract void Dao.get()
DaoImpl.get()
$Proxy0 intercepted public abstract void Dao.update()
DaoImpl.update()
$Proxy0 intercepted public abstract void Dao.delete()
DaoImpl.delete()

Ollie

Legacy Member
Javadoc van Proxy:

An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the Method object passed to invoke will be java.lang.Object. Other public methods of a proxy instance inherited from java.lang.Object are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan