Java 中静态代理与动态代理

2 篇文章 0 订阅

静态代理

代理接口
// 代理接口
public abstract class Subject {
    // 代理类与目标类共同实现的方法
    protected  abstract void operation();
}
目标类
// 目标类,实现了代理接口
public class RealObject extends Subject{
    @Override
    protected void operation() {
        System.out.println("do operation ...");
    }
}
代理类
// 代理类,实现了代理接口
public class ProxyObject extends Subject {
    // 目标类型
    private RealObject realObject;
    public ProxyObject(RealObject realObject) {
        this.realObject = realObject;
    }
    // 代理对象将客户端的调用委派给了目标对象,
    // 在调用目标对象之前与之后都可以执行某些特定操作.
    @Override
    protected void operation() {
        System.out.println("do something before real operation ...");
        if (realObject == null) {
            realObject = new RealObject();
        }
        realObject.operation();
        System.out.println("do something after real operation ...");
    }
}
客户端
// 客户端
public class Client {
    public static void main(String[] args) {
        ProxyObject proxyObject = new ProxyObject(new RealObject());
        // 客户端调用代理对象
        // 代理对象会将调用委派给目标对象
        proxyObject.operation();
    }
}

动态代理

代理接口
// 代理接口
public interface Subject {
    // 代理类与目标类都要执行的操作
    void shopping();
    void run();
}
目标类
// 目标类
public class Man implements Subject {
    @Override
    public void shopping() {
        System.out.println("shopping...");
    }
    @Override
    public void run() {
        System.out.println("run...");
    }
}
代理类
// 代理类
public class ManProxy implements InvocationHandler {
    //  目标对象
    private Object realObject;
    public ManProxy(Subject realObject) {
        this.realObject = realObject;
    }
    /**
     *
     * @param proxy 目标对象的代理
     * @param method 对应目标对象中的某个方法,在客户端代理对象调用哪个方法,这里的method就对应那个方法.
     * @param args 对应目标对象中某个方法的参数
     * @return
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 打印代理对象
        System.out.println(proxy.getClass().getName());
        System.out.println("before...");
        // 代理对象将客户端调用委派给目标对象
        method.invoke(realObject, args);
        System.out.println("after...");
        return null;
    }
}
客户端
public class Client {
    // 动态代理:代理类在程序运行时创建的代理方式
    public static void main(String[] args) {
        Man man = new Man();
        ManProxy manProxy = new ManProxy(man);
        /***
         * man.getClass().getClassLoader():目标类的类加载器
         * man.getClass().getInterfaces():目标类的接口,为代理类提供的接口
         * manProxy: 代理对象调用实现接口方法的时候最终调用到ManProxy.invoke().
         */
        // 获取目标类的代理对象
        Subject subject = (Subject) Proxy.newProxyInstance(man.getClass().getClassLoader(), man.getClass().getInterfaces(), manProxy);
        // 代理对象调用实现接口的方法shopping(),最终会调用到代理类中的invoke()
        subject.shopping();
        subject.run();
        // 打印代理对象
        System.out.println(subject.getClass().getName());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值