日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

动态代理源码分析,实现自己的动态代理

發(fā)布時(shí)間:2024/4/13 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态代理源码分析,实现自己的动态代理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是代理

增強(qiáng)一個(gè)對(duì)象的功能

買(mǎi)火車(chē)票,app就是一個(gè)代理,他代理了火車(chē)站,小區(qū)當(dāng)中的代售窗口

java當(dāng)中如何實(shí)現(xiàn)代理

java實(shí)現(xiàn)的代理的兩種辦法

代理的名詞

代理對(duì)象 增強(qiáng)后的對(duì)象

目標(biāo)對(duì)象 被增強(qiáng)的對(duì)象

他們不是絕對(duì)的,會(huì)根據(jù)情況發(fā)生變化

靜態(tài)代理

繼承

代理對(duì)象繼承目標(biāo)對(duì)象,重寫(xiě)需要增強(qiáng)的方法;

缺點(diǎn):會(huì)代理類(lèi)過(guò)多,非常復(fù)雜

聚合

目標(biāo)對(duì)象和代理對(duì)象實(shí)現(xiàn)同一個(gè)接口,代理對(duì)象當(dāng)中要包含目標(biāo)對(duì)象。

缺點(diǎn):也會(huì)產(chǎn)生類(lèi)爆炸,只不過(guò)比繼承少一點(diǎn)點(diǎn)

總結(jié):如果在不確定的情況下,盡量不要去使用靜態(tài)代理。因?yàn)橐坏┠銓?xiě)代碼,就會(huì)產(chǎn)生類(lèi),一旦產(chǎn)生類(lèi)就爆炸。

動(dòng)態(tài)代理

自己模擬的動(dòng)態(tài)代理

不需要手動(dòng)創(chuàng)建類(lèi)文件(因?yàn)橐坏┦謩?dòng)創(chuàng)建類(lèi)文件,就會(huì)產(chǎn)生類(lèi)爆炸),通過(guò)接口反射生成一個(gè)類(lèi)文件,然后調(diào)用第三方的編譯技術(shù),動(dòng)態(tài)編譯這個(gè)產(chǎn)生的類(lèi)文件成class文件,繼而利用UrlclassLoader(因?yàn)檫@個(gè)動(dòng)態(tài)產(chǎn)生的class不在工程當(dāng)中所以需要使用UrlclassLoader)把這個(gè)動(dòng)態(tài)編譯的類(lèi)加載到j(luò)vm當(dāng)中,最后通過(guò)反射把這個(gè)類(lèi)實(shí)例化。

缺點(diǎn):首先要生成文件

缺點(diǎn):動(dòng)態(tài)編譯文件 class

缺點(diǎn):需要一個(gè)URLclassloader

軟件性能的最終體現(xiàn)在IO操作

package com.leon.proxy;import com.leon.dao.CoustomInvocationHandler; import com.sun.jndi.toolkit.url.UrlUtil;import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader;public class ProxyUtil {/*** content --->string* .java io* .class**** .new 反射----》class* @return*/public static Object newInstance(Class targetInf, CoustomInvocationHandler h){Object proxy=null;//String handlerName = CoustomInvocationHandler.class.Method methods[] =targetInf.getDeclaredMethods();String line="\n";String tab ="\t";String infName = targetInf.getSimpleName();String content ="";String packageContent = "package com.google;"+line;String importContent = "import "+targetInf.getName()+";"+line+"import com.leon.dao.CoustomInvocationHandler;"+line+"import java.lang.Exception;"+"import java.lang.reflect.Method;"+line;String clazzFirstLineContent = "public class $Proxy implements "+infName+"{"+line;String filedContent =tab+"private CoustomInvocationHandler h;"+line;String constructorContent =tab+"public $Proxy (CoustomInvocationHandler h){" +line+tab+tab+"this.h =h;"+line+tab+"}"+line;String methodContent = "";for (Method method : methods) {String returnTypeName = method.getReturnType().getSimpleName();String methodName =method.getName();// Sting.class String.classClass args[] = method.getParameterTypes();String argsContent = "";String paramsContent="";int flag =0;for (Class arg : args) {String temp = arg.getSimpleName();//String//String p0,Sting p1,argsContent+=temp+" p"+flag+",";paramsContent+="p"+flag+",";flag++;}if (argsContent.length()>0){argsContent=argsContent.substring(0,argsContent.lastIndexOf(",")-1);paramsContent=paramsContent.substring(0,paramsContent.lastIndexOf(",")-1);}methodContent+=tab+"public "+returnTypeName+" "+methodName+"("+argsContent+")throws Exception {"+line+tab+tab+"Method method = Class.forName(\""+targetInf.getName()+"\").getDeclaredMethod(\""+methodName+"\");"+line+tab+tab+"return ("+returnTypeName+")h.invoke(method);"+line;methodContent+=tab+"}"+line;}content=packageContent+importContent+clazzFirstLineContent+filedContent+constructorContent+methodContent+"}";File file =new File("d:\\com\\google\\$Proxy.java");try {if (!file.exists()) {file.createNewFile();}FileWriter fw = new FileWriter(file);fw.write(content);fw.flush();fw.close();JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);Iterable units = fileMgr.getJavaFileObjects(file);JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);t.call();fileMgr.close();URL[] urls = new URL[]{new URL("file:D:\\\\")};URLClassLoader urlClassLoader = new URLClassLoader(urls);Class clazz = urlClassLoader.loadClass("com.google.$Proxy");Constructor constructor = clazz.getConstructor(CoustomInvocationHandler.class);proxy = constructor.newInstance(h);//clazz.newInstance();//Class.forName()}catch (Exception e){e.printStackTrace();}/*** public UserDaoLog(UserDao target){* this.target =target;** }*/return proxy;} }

JDK動(dòng)態(tài)代理

通過(guò)接口反射得到字節(jié)碼,然后把字節(jié)碼轉(zhuǎn)成class native openJDK c++

?

總結(jié)

以上是生活随笔為你收集整理的动态代理源码分析,实现自己的动态代理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。