使用Arthas查看JDK代理源码

【README】

本文总结自黑马程序员-设计模式,老师讲的非常棒;

【1】jdk代理案例

卖票接口

public interface SellTickets2 {
    void sell();
}

火车站

public class TrainStation2 implements SellTickets2 {

    @Override
    public void sell() {
        System.out.println("火车站卖票");
    }
}

jdk代理工厂

public class JdkProxyFactory {

    // 声明目标对象
    private TrainStation2 trainStation = new TrainStation2();

    public SellTickets2 getProxyObject(){
        return (SellTickets2) Proxy.newProxyInstance(
                TrainStation2.class.getClassLoader(),
                TrainStation2.class.getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("代售点收取服务费5元-jdk动态代理");
                        // 执行目标对象方法
                        Object returnObject = method.invoke(trainStation, args);
                        return returnObject;
                    }
                }
        );
    }
}

测试案例;

public class JdkProxyTest {
    public static void main(String[] args) {
        JdkProxyFactory jdkProxyFactory = new JdkProxyFactory();
        SellTickets2 proxyObject = jdkProxyFactory.getProxyObject();
        proxyObject.sell();

        System.out.println(proxyObject.getClass());
        while (true); // 死循环只是为了让当前线程不结束,内存不被回收
    }
}

【2】通过Arthas查看JDK代理源码 

1)下载 arthas, 快速入门 | arthas

2)解压后,在命令行执行:

C:\Users\pacoson>cd D:\software_cluster\arthas\arthas-bin

C:\Users\pacoson>d:

D:\software_cluster\arthas\arthas-bin>java -jar arthas-boot.jar

3)录入jvm线程编号【4】

 4)jad命令查看clazz类源码:

[arthas@18092]$ jad com.sun.proxy.$Proxy0 
[arthas@18092]$ jad com.sun.proxy.$Proxy0

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@56d54148

Location:

/*
 * Decompiled with CFR.
 *
 * Could not load the following classes:
 *  com.cmc.designpattern.patterns.proxy.jdk_proxy.SellTickets2
 */
package com.sun.proxy;

import com.cmc.designpattern.patterns.proxy.jdk_proxy.SellTickets2;
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 SellTickets2 {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;
  
// ................................................

5)删除冗余代码后的Proxy类核心代码如下:

package com.sun.proxy;

import com.cmc.designpattern.patterns.proxy.jdk_proxy.SellTickets2;
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 SellTickets2 {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler invocationHandler) {
        super(invocationHandler);
    }

    static {
        m3 = Class.forName("com.cmc.designpattern.patterns.proxy.jdk_proxy.SellTickets2").getMethod("sell", new Class[0]);
    }

    public final void sell() {       
      this.h.invoke(this, m3, null);                   
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值