黑马程序员——java加强之代理
来源:互联网 发布:掷骰子抽奖js特效 编辑:程序博客网 时间:2024/05/02 04:28
代理
一、 静态代理,一般分为 类继承代理与对象组合代理。 类继承就是继承超类获得超类的功能。
在应用中,一般用组合代理。
如下图:
二、在java应用中,动态代理应用更广泛,可以说这是java语言的特性。
public class SetProxyFactory {
@SuppressWarnings("unchecked")
publicstatic <T> T getProxy(final T obj) {
//类加载器、类的接口、一个InvocationHandler实现
return(T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(),new InvocationHandler() {
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
System.out.println("Start....");
returnmethod.invoke(obj, args);
}
});
}
publicstatic void main(String[] agrs) throws ClassNotFoundException {
Set<String>set = new HashSet<String>();// 创建一个类
Set<String>proxySet = SetProxyFactory.getProxy(set);// 有类生成一个代理对象
System.out.println(Proxy.getInvocationHandler(proxySet));
System.out.println(proxySet.size());
}
}
- 动态代理主要涉及到 Proxy类与InvocationHandler类。
- Proxy有一个 public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)返回值是一个由JVM动态生成的类所实例化的对象,可以认为InvocationHandler 是这个类的变量属性。
- loader是类加载器
- interfaces 是接口列表
- InvocationHandler 是一个InvocationHandler 的实例。
- InvocationHandler有一个接口: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;此接口可以认为是回调函数,也就是代理的类的对象 被访问时候,就会触发它所绑定的 InvocationHandler 的invoke方法。传来的差数有代理类,方法,差数列表。在invoke方法一般有method.invoke(obj, args)调用,obj真正的实例。
- Proxy有一个 public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)返回值是一个由JVM动态生成的类所实例化的对象,可以认为InvocationHandler 是这个类的变量属性。
- 动态关键类还是Proxy类的newProxyInstance方法,我们可以进入源码一看究竟。
public static ObjectnewProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throwsIllegalArgumentException
{
if(h == null) {
throw new NullPointerException();
}
/*
* Look up or generate the designated proxyclass.
*/
Classcl = getProxyClass(loader, interfaces);//关键是创建代理类
/*
* Invoke its constructor with the designatedinvocation handler.
*/
try{
Constructor cons =cl.getConstructor(constructorParams);
return (Object) cons.newInstance(newObject[] { h });//InvocationHandler是作为一个实例变量传入代理类中。
}catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}catch (IllegalAccessException e) {
throw new InternalError(e.toString());
}catch (InstantiationException e) {
throw new InternalError(e.toString());
}catch (InvocationTargetException e) {
throw new InternalError(e.toString());
}
}
关键还是 Classcl = getProxyClass(loader, interfaces); getProxyClass方法,该方法的差数是 ClassLoader 与 Classinterfaces。此方法中主要分为:
- 检查 ,一般有:接口数目不能大于65535,禁止非接口,禁止有重复的接口等。
- 缓存并复用。
- 定义名称
long num;
synchronized(nextUniqueNumberLock) {
num = nextUniqueNumber++;
}
String proxyName = proxyPkg +proxyClassNamePrefix + num;
5创建代理类。代码如下
/*
* Generate the specified proxy class.
*/
byte[]proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces); 主要是此方法,生成了 字节码。 如果要看,建议使用openjdk及看看jvm字节码
try{
proxyClass = defineClass0(loader,proxyName,
proxyClassFile,0, proxyClassFile.length);
-
- 最后调用 defineClass0 根据字节码生成代理类。
- 我们可以看下动态代理的类图
- 在上图中$ProxyN是代理类。继承Proxy类。在实现了接口。$ProxyN其实跟User是没有关系的。调用是通过AInvocationHandler来实现的。
- 黑马程序员——java基础加强之代理
- 黑马程序员——java加强之代理
- 黑马程序员—java之基础加强
- 黑马程序员java学习<基础加强>—动态代理
- 黑马程序员—Java基础加强(动态代理)
- 黑马程序员-java加强-代理
- 黑马程序员——Ⅲjava基础加强之动态代理(15)
- 黑马程序员:基础加强之动态代理
- 黑马程序员--加强之动态代理
- 黑马程序员_基础加强之代理
- 黑马程序员-JAVA基础加强-代理
- 黑马程序员 java基础加强_代理
- 黑马程序员 Java加强 动态代理
- 黑马程序员-java基础加强-代理
- 黑马程序员---java基础加强---动态代理
- 黑马程序员-->Java基础加强-->动态代理
- 黑马程序员---Java基础加强---代理
- 黑马程序员——java加强之反射、内省
- hdu45221——小明系列问题——小明序列 线段树优化dp
- 定时关闭消息对话框
- 滑动ListView自动隐藏页面头部和底部元素
- lua 与 c/c++ 交互(3)c/c++ 调用 lua 数组类型 table
- 重载new和delete来防止c++工程中内存泄漏
- 黑马程序员——java加强之代理
- Get Start StrangeIOC for Unity3D
- Automatic Editing(字符串替换)
- 第十五周项目二-阅读程序2
- hdu~2795(线段树)
- iOS自定义控件之图像选取按钮
- 学习笔记_CCNx_20141204(1)
- Java并发编程之线程互斥笔记
- POJ 3729 Facer’s string