【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);
}
}