静态代理
代理类,代理对象在编译期生成
动态代理
代理类,代理对象在运行时生成
动态代理有JDK和CGLIB两种
public interface SellTickets { void sell(); }
// 火车站
public class TrainStation implements SellTickets{
public void sell() { System.out.println("火车站卖票"); }
}
// 代售点
// 代理对象和目标对象实现同样的接口
// 代理对象中维护了目标对象的引用
// 代理对象调用相应方法时,实际调用了目标对象的那个方法,只不过可能会在之前或之后做一些处理
public class ProxyPoint implements SellTickets{
private TrainStation trainStation = new TrainStation();
public void sell(){
System.out.println("代售点收取一些服务费用");
trainStation.sell();// 最终还是火车站\目标对象卖票,只不过代售点可能会在之前或之后做一些处理
}
}
// 通过代理对象来买票
public static void main(String[] args) {
ProxyPoint proxyPoint = new ProxyPoint();
proxyPoint.sell();
}
JDK动态代理
public static void main(String[] args) {
SellTickets proxy = getProxyObject(); // class com.sun.proxy.$Proxy0
proxy.sell();
}
private static SellTickets getProxyObject(){
// 目标对象
TrainStation station = new TrainStation();
// 代理对象
SellTickets proxy = (SellTickets)Proxy.newProxyInstance(
station.getClass().getClassLoader(),// 类加载器
station.getClass().getInterfaces(),// 实现的接口
new InvocationHandler() { // InvocationHandler接口的匿名实现类的对象
/**
* @param proxy: 代理对象proxy自己, 在invoke方法中基本不用
* @param method: 代理对象proxy调用的那个方法,比如上面调用的sell方法
* @param args: 代理对象调用方法时,传的参数
* @return: 代理对象proxy调用的那个方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代售点收取一定的服务费用(JDK动态代理)");
// 调用目标对象的对应方法
Object returnValue = method.invoke(station, args);
return returnValue;
}
}
);
return proxy;
}
运行时生成的,内存中的代理类$Proxy0
package com.sun.proxy;
import cn.Code.SellTickets;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 目标类和代理类都实现了同样的接口
public final class $Proxy0 extends Proxy implements SellTickets {
private static Method m3;
// InvocationHandler的实现类对象,在创建代理对象时已提供
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
// invoke方法的逻辑,在创建代理对象时已提供
public final void sell() throws {
super.h.invoke(this, m3, (Object[])null);
}
static {
m3 = Class.forName("cn.Code.SellTickets").getMethod("sell");
}
}
将运行时,内存中生成的代理类$Proxy0保存到磁盘中
// main方法的第一行加上这个,可以将内存中生成的代理类保存为class文件
System.setProperty("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
// 或者可以考虑使用下面命令,在UI端中操作
jhsdb hsdb
CGLIB动态代理
如果没有SellTickets接口,只有TrainStation类,这个时候使用CGLIB代理
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
// 火车站(目标类)
public class TrainStation{
// 如果sell方法在目标类中是final或private的,代理类中不会有sell方法
// (protected,public,default), 且不是final, 代理类中才会有增强的sell方法
// final:此时调用的是目标类中的sell方法,代理类中没有,不会有增强效果
// private:只能在目标类内部调用
public void sell() {
System.out.println("火车站卖票");
}
}
public static void main(String[] args) {
// cn.Code.TrainStation$$EnhancerByCGLIB$$e0808941
TrainStation proxy = getProxyObject();
proxy.sell();
}
private static TrainStation getProxyObject(){
// 目标对象
TrainStation station = new TrainStation();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TrainStation.class);//指定父类
enhancer.setCallback(new MethodInterceptor() {//设置CallBack
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代售点收取一定的服务费用(CGLIB代理)");
Object returnValue = method.invoke(station, objects);
return returnValue;
}
});
// 代理对象
TrainStation proxy = (TrainStation) enhancer.create();
return proxy;
}
运行时,生成的代理类TrainStation$$EnhancerByCGLIB$$e0808941
package cn.Code;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class TrainStation$$EnhancerByCGLIB$$e0808941 extends TrainStation implements Factory {
private boolean CGLIB$BOUND;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static final Method CGLIB$sell$0$Method;
private static final MethodProxy CGLIB$sell$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
public TrainStation$$EnhancerByCGLIB$$e0808941() {
CGLIB$BIND_CALLBACKS(this);
}
// 设置CGLIB$CALLBACK_0
private static final void CGLIB$BIND_CALLBACKS(Object var0) {
TrainStation$$EnhancerByCGLIB$$e0808941 var1 = (TrainStation$$EnhancerByCGLIB$$e0808941)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
}
var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
}
}
static {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("cn.Code.TrainStation$$EnhancerByCGLIB$$e0808941");
Class var1;
CGLIB$sell$0$Method = ReflectUtils.findMethods(new String[]{"sell", "()V"}, (var1 = Class.forName("cn.Code.TrainStation")).getDeclaredMethods())[0];
CGLIB$sell$0$Proxy = MethodProxy.create(var1, var0, "()V", "sell", "CGLIB$sell$0");
}
public Object newInstance(Callback[] var1) {
CGLIB$THREAD_CALLBACKS.set(var1);// 设置CallBack
TrainStation$$EnhancerByCGLIB$$e0808941 var10000 = new TrainStation$$EnhancerByCGLIB$$e0808941();
CGLIB$THREAD_CALLBACKS.set((Callback[])null);// 清空CallBack
return var10000;
}
// 当目标类中sell方法为protected或public或default,且不为final时,代理类中才会有这个方法
public final void sell() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
// 增强逻辑
var10000.intercept(this, CGLIB$sell$0$Method, CGLIB$emptyArgs, CGLIB$sell$0$Proxy);
} else {
super.sell();
}
}
final void CGLIB$sell$0() {
super.sell();
}
}