动态代理
JDK 动态代理
创建接口及具体实现类
public interface BingoOk {
/**
*
* @param who
* @return
*/
public String lookLook(String who);
/**
*
* @return
*/
public String ohMyGod();
}
public class BingoOkImpl implements BingoOk{
@Override
public String lookLook(String who) {
System.out.println("推开门了");
return "让"+who+"来看看~~";
}
@Override
public String ohMyGod() {
System.out.println("赶紧跑");
return "oh my god,看到了啥!!!";
}
}
实现InvocationHandler 接口的invoke方法
public class JDKProxyLearn implements InvocationHandler {
private Object object;
/**
* 指定需要代理的对象
* @param object
*/
public JDKProxyLearn(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke 来了。偷窥开始~");
System.out.println("method : "+method);
Object invoke = method.invoke(object,args);
System.out.println("invoke 完了。偷窥完了~");
return invoke;
}
}
具体方法及实现
public class TestJDKProxy {
public static void main(String[] args) {
BingoOk ok = new BingoOkImpl();
// 实现 InvocationHandler 接口,传入ok接口 代理 这个ok。具体嵌入方法
InvocationHandler handler = new JDKProxyLearn(ok);
//获取 需要代理的 ok 接口的 classloader
ClassLoader classLoader = ok.getClass().getClassLoader();
//获取 需要代理的 ok 接口的 interfaces
Class<?>[] interfaces = ok.getClass().getInterfaces();
// 指定代理的 classloader ,interfaces 还有 执行
BingoOk o = (BingoOk)Proxy.newProxyInstance(classLoader, interfaces, handler);
System.out.println("代理了呀 : " +o.getClass().getName());
String value = o.lookLook("海少");
System.out.println(value);
// String s = o.ohMyGod();
// System.out.println(s);
}
}
关键方法是 Proxy.newProxyInstance
,对应生成的最终的class可以发现,对象 继承了 Proxy类 实现了 自定义的接口。 因为Java 单继承多实现,所以 JDK动态代理对象不支持对实现类的代理,只支持接口的代理。
CGLIB 动态代理
直接新建需要代理的类
public class BingoOk {
public String lookLook(String who) {
System.out.println("推开门了");
return "让"+who+"来看看~~";
}
public String ohMyGod() {
System.out.println("赶紧跑");
return "oh my god,看到了啥!!!";
}
}
实现MethodInterceptor的intercept方法
public class CGLibProxyLearn implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("invoke 来了。偷窥开始~");
System.out.println("method : "+method);
Object invoke = methodProxy.invokeSuper(o,objects);
System.out.println("invoke 完了。偷窥完了~");
return invoke;
}
}
具体方法及实现
public class TestCGLibProxy {
public static void main(String[] args) {
BingoOk ok = new BingoOk();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ok.getClass());
enhancer.setCallback(new CGLibProxyLearn());
BingoOk instance = (BingoOk)enhancer.create();
System.out.println("代理开始了" + instance.getClass().getName());
String value = instance.lookLook("海少2");
System.out.println(value);
}
}
关键注意Enhancer 增强类,设置增强类的类型,和代理方法。创建代理对象并通过代理对象执行。对应生成的最终的class可以发现,代理对象继承了 实现类,实现了 Factory 接口。所以相当于通过子类来实现的。