栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 动态代理,泛微网络java面试题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 动态代理,泛微网络java面试题

  • 原始方法1
  • @return String
    */
    String doSomething();


int printNum();
}

  • 目标类:

  • public class Target implements TargetInterface {

    @Override
    public String doSomething() {
    System.out.println(“doSomething”);
    return “doSomething”;
    }

    @Override
    public int printNum() {
    System.out.println(“printNum”);
    return 100;
    }
    }

    • 代理类逻辑处理:(不是真正的代理类)

    public class DynamicProxyHandler implements InvocationHandler {


    private final Object target;

    public DynamicProxyHandler(Object target) {
    this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    System.out.println(“do something before”);
    Object invoke = method.invoke(target, args);
    System.out.println(“do something after”);
    return invoke;
    }
    }

    • 动态代理对象生成:

    mport java.lang.reflect.Proxy;

    public class ProxyTest {

    public static void main(String[] args) {
    //1、创建被代理的目标对象
    Target target = new Target();
    //2、创建代理类处理器对象
    DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler(target);
    //3、创建代理类对象
    //a.JDK会通过传入的参数信息动态地在内存中创建和.class文件等同的字节码
    //b.然后会根据相应的字节码转换成对应的class
    //c.最后创建代理类实例
    TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), dynamicProxyHandler);

    System.out.println(“doSomething() call: " + proxy.doSomething());
    System.out.println(”------------------------");
    System.out.println("proxy.printNum() call: " + proxy.printNum());
    }
    }

    • 输出结果:
    do something before
    doSomething
    do something after
    doSomething() call: doSomething

    do something before
    printNum
    do something after
    proxy.printNum() call: 100

    2.1.2 原理说明
    • 具体步骤
    1. 通过实现InvovationHandler接口创建自己的调用处理器
    2. 通过为Proxy类指定ClassLoader对象和一组Interface来创建动态代理类
    3. 通过反射机制获取动态代理类的构造
    【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
    
    浏览器打开:qq.cn.hn/FTf 免费领取
    

    函数,其唯一参数类型是InvocationHandler接口类型
    4. 通过构造函数创建动态代理类实例,调用处理器对象(InvocationHandler接口的实现类实例)作为参数传入

    • Proxy类分析

    public class Proxy implements java.io.Serializable {

    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
    Class[] interfaces,
    InvocationHandler h)
    throws IllegalArgumentException {
    Objects.requireNonNull(h);

    final Class[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
    checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }


    Class cl = getProxyClass0(loader, intfs);


    try {
    if (sm != null) {
    checkNewProxyPermission(Reflection.getCallerClass(), cl);
    }

    final Constructor cons = cl.getConstructor(constructorParams);
    final InvocationHandler ih = h;

    return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
    throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
    Throwable t = e.getCause();
    if (t instanceof RuntimeException) {
    throw (RuntimeException) t;
    } else {
    throw new InternalError(t.toString(), t);
    }
    } catch (NoSuchMethodException e) {
    throw new InternalError(e.toString(), e);
    }
    }

    }


    private static Class getProxyClass0(ClassLoader loader,
    Class… interfaces) {
    if (interfaces.length > 65535) {
    throw new IllegalArgumentException(“interface limit exceeded”);
    }

    // 如果实现指定接口的代理类存在于指定加载器中,则直接返回缓存副本
    // 否则通过ProxyClassFactory创建代理类
    return proxyClassCache.get(loader, interfaces);
    }

    • ProxyClassFactory类生成代理类

    简单步骤就是先生成类的字节码文件,再通过Proxy类的defineClass0本地方法生成字节码文件。具体实现代码可以查看Proxy类的静态内部类ProxyClassFactory源码。

    • 字节码文件

    System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");方法修改系统变量,可以保存生成的字节码文件

    字节码文件:

    actory源码**。

    • 字节码文件

    System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");方法修改系统变量,可以保存生成的字节码文件

    [外链图片转存中…(img-06Y4pLMU-1636272455512)]

    字节码文件:

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/439777.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号