摘要:動(dòng)態(tài)代理即,動(dòng)態(tài)代理是利用反射技術(shù),在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)某些給定接口的新類。調(diào)用該方法調(diào)用類中的,參數(shù)為空的方法。
動(dòng)態(tài)代理
即,動(dòng)態(tài)代理是利用java反射技術(shù),在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)某些給定接口的新類。
栗子先定義接口
public interface people { public String work(); }
實(shí)現(xiàn)該接口
public class Teacher implements people{ @Override public String work() { System.out.println("教書育人"); return "教書"; } }
編寫代理類
import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class WorkHandler implements InvocationHandler { // 代理類的對(duì)象 private Object obj; public WorkHandler(){ } // 在調(diào)用這個(gè)方法的時(shí)候,會(huì)被調(diào)度到invoke方法,并將參數(shù)傳入 public WorkHandler(Object obj){ this.obj = obj; } // 在調(diào)用給類的方法的時(shí)候,會(huì)被調(diào)度到invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 真實(shí)對(duì)象執(zhí)行之前添加操作 // 調(diào)用obj類的method方法,并且參數(shù)為args Object invoke = method.invoke(obj, args); // 真實(shí)對(duì)象執(zhí)行后添加操作 return invoke;// 返回執(zhí)行的結(jié)果 } }
最后運(yùn)行
import java.io.FileInputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Main { public static void main(String[] args){ // 要代理的對(duì)象 people people = new Teacher(); // 創(chuàng)建要代理的真實(shí)對(duì)象 // 進(jìn)行注冊(cè) InvocationHandler handler = new WorkHandler(people); // 進(jìn)行創(chuàng)建代理對(duì)象 // 定義一個(gè)代理對(duì)象 people proxy; // 調(diào)用Proxy.newProxyInstance方法 // 需要傳入真實(shí)對(duì)象實(shí)現(xiàn)的接口,為下一步調(diào)用該方法做準(zhǔn)備 // 將handler關(guān)聯(lián)到invocationHandler對(duì)象,用于調(diào)度到invoke方法 // 由于返回的對(duì)象為object類型,需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換,保留people接口定義的方法 // 最后一個(gè)參數(shù)要對(duì)對(duì)象進(jìn)行關(guān)聯(lián),最后批量生產(chǎn)出對(duì)象 proxy = (people) Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler); System.out.println(proxy.work()); } }第一個(gè)參數(shù)
第一個(gè)參數(shù)是運(yùn)行時(shí),創(chuàng)建的代理對(duì)象。
反射+IO操作讀取class文件import java.io.FileInputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main { // 需要使用static讓其加載進(jìn)入內(nèi)存 static class myClassLoader extends ClassLoader{ private String classPath; // 獲取當(dāng)前類的在磁盤中保存的地址 // 通過(guò)構(gòu)造函數(shù)將地址注入 public myClassLoader(String classPath){ this.classPath = classPath; } // 將文件內(nèi)容加載進(jìn)入內(nèi)存 private byte[] loadByte(String name) throws Exception{ // 獲取一個(gè)輸入流, FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class"); // 獲取長(zhǎng)度 int len = fis.available(); // 定義byte數(shù)組 byte[] data = new byte[len]; // 加載進(jìn)入內(nèi)存 fis.read(data); // 關(guān)閉流 fis.close(); return data; } // 重寫findClass方法,讓加載的時(shí)候調(diào)用findClass方法 protected Class> findClass(String name) throws ClassNotFoundException{ try{ // 讀取文件到數(shù)組中 byte[] data = loadByte(name); // 將字節(jié)碼加載進(jìn)入內(nèi)存當(dāng)中 return defineClass(name, data, 0, data.length); }catch(Exception e){ e.printStackTrace(); } return null; } } public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException { // 先初始化該類 myClassLoader classLoader = new myClassLoader("/home/ming"); // 此時(shí)會(huì)調(diào)用findClass加載Test.class加載進(jìn)入內(nèi)存當(dāng)中 Class clazz = classLoader.loadClass("com.ming.Test"); // 實(shí)例化該類對(duì)象 Object obj = clazz.newInstance(); // 獲取clazz該類方法中名稱為hello,參數(shù)為空的方法。 Method helloMethod = clazz.getDeclaredMethod("helloWorld", null); // 調(diào)用該方法 // 調(diào)用obj類中的helloMethod,參數(shù)為空的方法。 helloMethod.invoke(obj, null); } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73124.html
摘要:網(wǎng)上關(guān)于的動(dòng)態(tài)代理,和這些概念有講解得非常高深的文章。現(xiàn)在咱們通過(guò)一個(gè)最簡(jiǎn)單的例子認(rèn)識(shí)什么是。創(chuàng)建一個(gè)簡(jiǎn)單的類,實(shí)現(xiàn)這個(gè)接口。看看用如何優(yōu)雅實(shí)現(xiàn)吧希望這個(gè)例子能讓大家對(duì)的動(dòng)態(tài)代理之有了最基本的了解。 網(wǎng)上關(guān)于Java的動(dòng)態(tài)代理,Proxy和InvocationHandler這些概念有講解得非常高深的文章。其實(shí)這些概念沒(méi)有那么復(fù)雜。現(xiàn)在咱們通過(guò)一個(gè)最簡(jiǎn)單的例子認(rèn)識(shí)什么是Invocatio...
摘要:網(wǎng)上關(guān)于的動(dòng)態(tài)代理,和這些概念有講解得非常高深的文章。現(xiàn)在咱們通過(guò)一個(gè)最簡(jiǎn)單的例子認(rèn)識(shí)什么是。創(chuàng)建一個(gè)簡(jiǎn)單的類,實(shí)現(xiàn)這個(gè)接口。看看用如何優(yōu)雅實(shí)現(xiàn)吧希望這個(gè)例子能讓大家對(duì)的動(dòng)態(tài)代理之有了最基本的了解。 網(wǎng)上關(guān)于Java的動(dòng)態(tài)代理,Proxy和InvocationHandler這些概念有講解得非常高深的文章。其實(shí)這些概念沒(méi)有那么復(fù)雜。現(xiàn)在咱們通過(guò)一個(gè)最簡(jiǎn)單的例子認(rèn)識(shí)什么是Invocatio...
摘要:代理模式基本概念不論是靜態(tài)代理還是動(dòng)態(tài)代理其本質(zhì)都是代理模式的一種實(shí)現(xiàn)那么什么是代理模式呢代理模式即給某一個(gè)對(duì)象提供一個(gè)代理并由代理對(duì)象控制對(duì)原對(duì)象的引用代理模式其實(shí)取材于實(shí)際生活例如我們生活中常見的房屋租賃代理我們?cè)谧夥繒r(shí)一般不是直接和房 代理模式 基本概念 不論是靜態(tài)代理還是動(dòng)態(tài)代理, 其本質(zhì)都是代理模式的一種實(shí)現(xiàn), 那么什么是代理模式呢?代理模式, 即給某一個(gè)對(duì)象提供一個(gè)代理, ...
時(shí)間:2017年08月28日星期一說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:代理模式 1-1 概念介紹 學(xué)習(xí)本課程基礎(chǔ) 面向?qū)ο蟮脑O(shè)計(jì)思維 了解多態(tài)的概念 了解反射機(jī)制 課程目標(biāo) 代理模式基本概念及分類...
摘要:修飾者模式設(shè)計(jì)模式中的修飾者模式能動(dòng)態(tài)地給目標(biāo)對(duì)象增加額外的職責(zé)。修飾者模式調(diào)用的時(shí)序圖如下圖所示。的實(shí)現(xiàn)原理和修飾者模式類似。 ?在上邊一篇文章中我們介紹了Spring AOP的基本概念,今天我們就來(lái)學(xué)習(xí)一下與AOP實(shí)現(xiàn)相關(guān)的修飾者模式和Java Proxy相關(guān)的原理,為之后源碼分析打下基礎(chǔ)。 修飾者模式 ?Java設(shè)計(jì)模式中的修飾者模式能動(dòng)態(tài)地給目標(biāo)對(duì)象增加額外的職責(zé)(Respon...
閱讀 2432·2021-11-22 13:53
閱讀 1126·2021-09-22 16:06
閱讀 1370·2021-09-02 15:21
閱讀 1895·2019-08-30 15:55
閱讀 3116·2019-08-29 11:19
閱讀 1911·2019-08-26 13:23
閱讀 931·2019-08-23 18:23
閱讀 1748·2019-08-23 16:06