静态代理与动态代理模式demo实现

代理模式

概念

​ 为其他对象提供一种代理以控制这个对象的访问,在某些情况下一个对象不能直接访问那个对象时,代理就起到了客户端和被代理对象(委托类)中介作用。 代理类和委托类都有同样接口。

好处

​ 可以不用动原来类的逻辑,再次增加一些功能,符合开闭原则。真正的业务还是交给被代理对象处理的,因此在其委托被代理对象处理业务前后实现一些公共逻辑服务,例如加入缓存或日志等功能,无须修改原来的类就可以使用代理进行实现。

静态代理模式

​ 房东(Host)与中介(Proxy)共同实现了同一个接口(出租Rent), 中介给房东代理出租房子, 在出租过程中添加了中介的附属工作.

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

    public Proxy(Host host) {
        this.host=host;
    }
    @Override
    public void rent() {
        host.rent();
        release();
        see();
        receive();
    }

    public void release(){
        System.out.println("发布信息");
    }
    
    public void see(){
        System.out.println("看看房子");
    }

    public void receive(){
        System.out.println("收钱");
    }

}
public class Client {
    public static void main(String[] args) {
        Host host =new Host();
        //代理
        Proxy proxy = new Proxy(host);
        proxy.rent();
    }
}

动态代理模式

**静态代理:代理类由程序员创建的然后编译成.class文件。但是其中缺点是,具有重复代码,灵活性不好,例如在执行接口A中所有方法之前加上日志逻辑,那么使用静态代理的话,在代理类中每个方法都得加,如果我想add 开头方法加上一种逻辑,select 开头方法加上另一种逻辑,那么就很难去实现和维护了,想解决以上困惑就要使用动态代理了。

**动态代理:**是在运行的时候,通过jvm中的反射进行动态创建对象,生成字节码对象(构造方法参数 InvocationHandler h类型),传入由我们实现InvocationHandler接口的对象,通过反射创建代理对象。 然后当调用代理对象的任何方法都会调用h中的 invoke(Object proxy,Method method,Object[] args)传入当前代理对象、当前调用的方法、方法参数值。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 动态代理处理类
public class ProxyInvocationHandler implements InvocationHandler {

    // 被代理的接口
    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 {

        // 动态代理的本质, 就是使用反射机制实现
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }
    public void log(String name){
        System.out.println("执行了"+name+"方法");
    }

}

使用动态代理

public class Client {
    public static void main(String[] args) {
        //真实角色
        Rent rent = new Host();
        //代理角色, 不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        // 设置要代理的对象
        pih.setTarget(rent);
        //动态生成代理类
        Rent proxy = (Rent) pih.getProxy();
        proxy.rent();
    }
}

结果输出:

执行了rent方法
房东要出租房子

上一篇:CAS单点登录实现(包含原理配置实现及简易demo)


下一篇:Springboot全局异常处理+AOP记日志