Java Tutorial/Design Pattern/Proxy Pattern
Dynamic Proxies
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface MyClass {
void methodA(String s);
void methodB(int i);
String methodC(int i, String s);
}
public class DynamicProxyDemo {
public static void main(String[] clargs) {
MyClass prox = (MyClass) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyClass.class },
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("Method = " + method);
if (args != null) {
System.out.println("args = ");
for (int i = 0; i < args.length; i++)
System.out.println("\t" + args[i]);
}
return null;
}
});
System.out.println("about to call methodA");
prox.methodA("hello");
System.out.println("finish calling methodA");
prox.methodB(47);
prox.methodC(47, "hello");
}
}
Proxy: fronting for another object
interface ProxyBase {
void taskOne();
void taskTwo();
void taskThree();
}
class Implementation implements ProxyBase {
public void taskOne() {
System.out.println("Implementation.f()");
}
public void taskTwo() {
System.out.println("Implementation.g()");
}
public void taskThree() {
System.out.println("Implementation.h()");
}
}
class Proxy implements ProxyBase {
private ProxyBase implementation;
public Proxy() {
implementation = new Implementation();
}
public void taskOne() {
implementation.taskOne();
}
public void taskTwo() {
implementation.taskTwo();
}
public void taskThree() {
implementation.taskThree();
}
}
public class ProxyDemo {
public static void main(String args[]) {
Proxy p = new Proxy();
p.taskOne();
p.taskTwo();
p.taskThree();
}
}
The PoolManager using Proxy
import java.util.ArrayList;
class PoolItem {
boolean inUse = false;
Object item;
PoolItem(Object item) {
this.item = item;
}
}
class ReleasableReference { // Used to build the proxy
private PoolItem reference;
private boolean released = false;
public ReleasableReference(PoolItem reference) {
this.reference = reference;
}
public Object getReference() {
if (released)
throw new RuntimeException("Tried to use reference after it was released");
return reference.item;
}
public void release() {
released = true;
reference.inUse = false;
}
}
class PoolManager {
private ArrayList<PoolItem> items = new ArrayList<PoolItem>();
public void add(Object item) {
items.add(new PoolItem(item));
}
public static class EmptyPoolItem {
}
public ReleasableReference get() {
for (int i = 0; i < items.size(); i++) {
PoolItem pitem = (PoolItem) items.get(i);
if (pitem.inUse == false) {
pitem.inUse = true;
return new ReleasableReference(pitem);
}
}
return null;
}
}
interface Connection {
Object get();
void set(Object x);
void release();
}
class ConnectionImplementation implements Connection {
public Object get() {
return null;
}
public void set(Object s) {
}
public void release() {
}
}
class ConnectionPool { // A singleton
private static PoolManager pool = new PoolManager();
private ConnectionPool() {
}
public static void addConnections(int number) {
for (int i = 0; i < number; i++)
pool.add(new ConnectionImplementation());
}
public static Connection getConnection() {
ReleasableReference rr = (ReleasableReference) pool.get();
if (rr == null)
return null;
return new ConnectionProxy(rr);
}
}
class ConnectionProxy implements Connection {
private ReleasableReference implementation;
public ConnectionProxy(ReleasableReference rr) {
implementation = rr;
}
public Object get() {
return ((Connection) implementation.getReference()).get();
}
public void set(Object x) {
((Connection) implementation.getReference()).set(x);
}
public void release() {
implementation.release();
}
}
public class ConnectionPoolProxyDemo {
public static void main(String args[]) {
try {
ConnectionPool.addConnections(5);
Connection c = ConnectionPool.getConnection();
c.set(new Object());
c.get();
c.release();
c = ConnectionPool.getConnection();
c.set(new Object());
c.get();
c.release();
c.get();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}