动态代理和静态代理同属于代理模式。所不同的是,在Java中,动态代理的代理者对象是由Jdk给我们提供的。
以上次租房为案例,真实角色和共同接口如下:
// 共同的接口
interface Rent{
abstract void rentHouse();
}
// 真实对象
class Person implements Rent{
@Override
public void rentHouse() {
System.out.println("Person rent house");
}
}
不同的是,代理对象不用我们一次次的手动提供了
// 代理对象
class ProxyHandler implements InvocationHandler {
private Object obj;
public Object bind(Object obj) {
this.obj = obj;
// 返回被代理对象的实例
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
// AOP编程,如数据库事务
//if(method.getName().equals("save/update/delete...")) {..}
// 调用真正要执行的方法
result = method.invoke(obj, args);
// AOP...
return result;
}
}
- 和静态代理类似,动态代理中代理者也要持有被代理者的引用,这里用Object这个所有类的父类接收,这样动态代理就具有了更多的通用性。
- 联系上个实例,在静态代理中,我们手动实现了某个类的某个具体接口。而在动态代理中则不同,我们是通过反射,拿到类的实例和相应的接口,然后通过invoke方法来调用,这样同样是获得了更好的通用性,不必拘泥于某个具体的类了。
- 在invoke方法调用时,我们可以进行一些其他的操作。例如Java中的AOP编程中,实现事务就是如此
最后是使用上面的动态代理
public static void main(String[] args) {
ProxyHandler proxyHandler = new ProxyHandler();
Rent rentProxy = (Rent) proxyHandler.bind(new Person());
rentProxy.rentHouse();
}