静态代理和动态代理的简单实现

静态代理

公共的接口(出租房子)

public interface Rent {
    void rent();
}

真实的对象(被代理的对象 比如房东)

public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

代理对象(比如中介)

public class ProxyRent {
    private Host host;

    public void setHost(Host host) {
        this.host = host;
    }

    public void invoke(){
        // 这里先看房子再租房子
        this.seeHouse();
        host.rent();
    }

    // 实际业务中可能要增加一些其他业务,但是又要不改变被代理类中的业务
    // 比如我现在要增加一个中介带看房的业务

    private void seeHouse(){
        System.out.println("中介带看房子!");
    }
}

最后就是真实的租房者

public class Client {
    public static void main(String[] args) {
        ProxyRent proxyRent = new ProxyRent();
        Host host = new Host();
        proxyRent.setHost(host);
        proxyRent.invoke();
    }
}
image.png

这里就是在没有改变原代码的前提下,新增了一个带看房子的业务。

静态代理有比较大的局限性,一个代理类只能代理一个被代理的类,那么当被代理类比较多的时候,那么就需要些很多重复的代码了,在简单的场景中使用比较合适,复杂的场景就可以使用下面的动态代理方式了。

动态代理有两种使用比较广泛的方式实现,他们的底层原理其实差不多,一种是JDK原生的方式,另一种就是CGLib,下面的实例采用JDK的方式实现。

先写出两个接口,以便等会儿做演示

public interface Rent {
    void rent();
}
public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}

然后时它们的实现类,也就是需要被代理的类

public class Host implements Rent {
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}
public class User implements UserService{
    @Override
    public void add() {
        System.out.println("新增一个用户!");
    }

    @Override
    public void delete() {
        System.out.println("删除一个用户!");
    }

    @Override
    public void update() {
        System.out.println("修改一个用户!");
    }

    @Override
    public void query() {
        System.out.println("查询一个用户!");
    }
}

然后就是比较关键的一个类了,我们需要实现InvocationHandler接口

public class ProxyInvocationHandler implements InvocationHandler {

    // 这里采用Object类型,就可以代理不同的类了。
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    // 生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        this.log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }

    // 新增其他业务
    public void log(String type){
        System.out.println(type + "操作。");
    }
}

最后测试一下

public class Client {
    public static void main(String[] args) {
        // 代理User对象
//        User user = new User();
//
//        ProxyInvocationHandler handler = new ProxyInvocationHandler();
//
//        handler.setTarget(user);
//        UserService proxy = (UserService) handler.getProxy();
//
//        proxy.delete();

        // 代理Host对象
        Host host = new Host();
        ProxyInvocationHandler handler = new ProxyInvocationHandler();
        handler.setTarget(host);

        Rent proxy = (Rent) handler.getProxy();

        proxy.rent();
    }
}
image.png

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容