设计模式之动态代理

动态代理和静态代理同属于代理模式。所不同的是,在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();
    }