实现步骤:
1,创建接口,指定规范
2,目标类实现接口
3,创建获取代理类的类 (为什么这样说?因为代理类是运行时动态生成的,所以是在内存中,而且其类型是$Proxy0 ,如何进行分析可以用阿里巴巴的Arthas 来看,具体使用看最后的拓展),使用反射,对指定的方法进行扩展增强。往往借助使用的是Proxy.newProxyInstance,具体的参数传递代表含义看代码注释。
分布:
各个类描述:
SeckillTickets 接口:
package 代理对象.JDK动态代理;
//
public interface SeckillTickets {
public void sell();
}
TrainStation 类工厂:
package 代理对象.JDK动态代理;
//目标类,类似于拥有货源的工厂。
public class TrainStation implements SeckillTickets {
@Override
public void sell() {
System.out.println("这是TrainStation 的调用。");
}
}
ProxyClass 类:
package 代理对象.JDK动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*1,创建接口,指定规范
2,目标类实现接口
3,创建代理类,使用反射,对指定的方法进行扩展增强。往往借助使用的是Proxy.newProxyInstance,具体的参数传递代表含义看代码注释。*/
public class ProxyClass {
public static void main(String[] args) {
SeckillTickets target = new TrainStation();
//第一个参数是获得目标类的类加载器。
//第二个参数是目标类实现的所有接口。
SeckillTickets proxy = (SeckillTickets) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("先执行扩展增强的方法");
//这里的method就代表,被代理的目标类的代理的方法,使用method.invoke()就是这样的写法,表示调用。
//method.invoke 的第一个参数是目标对象,第二个是传给方法的参数,这样就知晓了调用的是哪个目标对象的哪个方法。
Object invoke = method.invoke(target, args);
return invoke;
}
});
//这里来调用方法,这样就知晓了增强的是哪个方法。
proxy.sell();
}
}
拓展:
1,下载Arthas-boot的jar包
https://arthas.aliyun.com/arthas-boot.jar
2,上面的ProxyClass 类,在最后添加两行代码。
public class ProxyClass {
public static void main(String[] args) {
SeckillTickets target = new TrainStation();
//第一个参数是获得目标类的类加载器。
//第二个参数是目标类实现的所有接口。
SeckillTickets proxy = (SeckillTickets) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("先执行扩展增强的方法");
//这里的method就代表,被代理的目标类的代理的方法,使用method.invoke()就是这样的写法,表示调用。
//method.invoke 的第一个参数是目标对象,第二个是传给方法的参数,这样就知晓了调用的是哪个目标对象的哪个方法。
Object invoke = method.invoke(target, args);
return invoke;
}
});
//这里来调用方法,这样就知晓了增强的是哪个方法。
proxy.sell();
//新添加的类。
System.out.println(proxy.getClass().getName());
while (true){
}
}
}
3,然后运行此类,得到:
4,运行Arthas。 按照
5,然后使用jad 命令 + 代理类的全名称,就可以得到代理类的全部信息。
其中有一个sell 方法:实际上上面使用代理对象调用的sell 方法是这个生成的代理类的sell 的方法。