设计模式(代理)

静态代理

静态代理使用硬编码的方式实现代理。

public interface Singer {

    public void sing();
}
提供实现类
public class Linjunjie implements Singer {

    @Override
    public void sing() {
        System.out.println("全都怪我,不该沉默时沉默。。。。");
    }
}
代理类
public class ProxySinger implements Singer{
    private Singer proxy;

    public ProxySinger(Singer singer){
        proxy = singer;
    }

    @Override
    public void sing() {
        System.out.println("前置增强处理。。");
        proxy.sing();
        System.out.println("后置增强处理。。");

    }
}
测试
   Singer singer = new ProxySinger(new Linjunjie());
   singer.sing();

前置增强处理。。
全都怪我,不该沉默时沉默。。。。
后置增强处理。。

JDK 动态代理

为接口中的方法提供对应的代理增强。

  1. 只有接口中的方法,才会有对应的代理方法
  2. 除此之外,还有一些方法也提供了代理。 (toString、hashCode、equals)。从这个层面上来讲,Interface 其实继承了Object

Object中的非本地 public 方法只有toString、hashCode、equals
在这里插入图片描述

JDK 代理的流程:

  1. 生成代理类的源码文件
  2. 编译、加载源码文件,并生成代理对象
  3. 调用代理对象的方法,触发 回调函数 invoke
定义接口类
public interface Singer {

    public void sing();
}
提供实现类
public class Linjunjie implements Singer {

    @Override
    public void sing() {
        System.out.println("全都怪我,不该沉默时沉默。。。。");
    }
}
定义回调函数
public class MyHandler implements InvocationHandler {

    private Object proxy;
    public MyHandler(Object object) {
        proxy = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前奏准备");
        Object obj = method.invoke(this.proxy, args);
        System.out.println("高潮不断");
        return obj;
    }

    public Object getInstance() {
        return Proxy.newProxyInstance(proxy.getClass().getClassLoader(),proxy.getClass().getInterfaces(), this);
    }

}
测试类
  		// 保存生成的代理类的字节码文件
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        // 回调方法
        MyHandler myHandler = new MyHandler(new Linjunjie());
        Singer singer = (Singer) myHandler.getInstance();
        singer.sing();
代理类源码文件

生成文件位置的
在这里插入图片描述

生成的源码文件

package com.sun.proxy;

import design.proxy.Singer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Singer {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void sing() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("design.proxy.Singer").getMethod("sing");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

  Method m3 = Class.forName("design.proxy.Singer").getMethod("sing");

  public final void sing() throws  {
        try {
        	// 代理类继承 Proxy,此处h为InvocationHandler
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

【Proxy】

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

【Proxy.ProxyClassFactory】,通过 ProxyClassFactory 生成字节流源码文件。

// 包名 + $Proxy + 自增的数字
 String proxyName = proxyPkg + proxyClassNamePrefix + num;

// 生成二进制文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值