<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ? ? 寫這篇博客是為了解決《[Dota兄訂餐——靜態代理(java)](http://blog.csdn.net/xiaoxian8023/article/details/9261851)》 里最終的遺留問題。 ? ?想必大家都或多或少了解一些Dos命令,在調用外部程序時,經常會用到dos命令來完成。其中有一條萬能的命令,就是用Explorer.exe來打開任意程序,就相當于直接雙擊該程序。 ? ? ?先給大家看一下我們要調用的外部資源,放到一個文件夾中,包括圖片、音樂、視頻、文本文檔、word文檔、還有其他文檔,最后還會加上一個網址。 ![](https://box.kancloud.cn/2016-02-18_56c53c4864487.jpg) ? ? ?我把Dos命令寫入到一個bat中,也放入同一個文件夾中,命令如下: ~~~ @echo off rem 調用默認程序打開圖片 explorer 1.jpg rem 調用默認程序打開pdf explorer 42種方法全面提升寶寶的智能.pdf rem 調用默認程序打開快捷方式 explorer SSH視頻.lnk rem 調用默認程序打開文本文檔 explorer X光下看騰訊.txt rem 調用默認程序打開chm explorer 電腦故障維修大全.chm rem 調用默認程序打開mp4 explorer 黃梅戲女駙馬誰料皇榜中狀元選段.mp4 rem 調用默認程序打開flv explorer 馬云創業演講.flv rem 調用默認程序打開音樂 explorer 我會很誠實.mp3 rem 調用默認程序打開Word文檔 explorer 驗收標準V3.1.docx rem 調用默認瀏覽器打開百度 explorer http://www.baidu.com ~~~ ? ? ?現在我們雙擊這個bat文件,系統會自動調用相對應的默認程序去打開相應的文件。 ![](https://box.kancloud.cn/2016-02-18_56c53c487cd88.jpg) ![](https://box.kancloud.cn/2016-02-18_56c53c4893e8f.jpg) ? ? 在上面的例子中,每種格式的文件都對應一種默認的打開程序。而且這個默認程序是可以手動更換的。而Explorer就相當于這里面的動態代理。我們把具體的參數傳遞給代理Explorer,它會根據不同的文檔格式,啟動對應的默認程序,然后再執行相應的操作。當默認程序換了,就會啟動新設定的默認程序。而且不僅僅局限于一類文件或程序,而是可以打開任意程序或文檔。這就是動態代理模式的應用。 ? ? 靜態代理是一個代理類服務一個接口,且代理是針對于這個接口編寫特定代碼,其字節碼是編譯期生成。而動態代理的字節碼(即編譯后的class文件)在程序運行時由java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了簡化了編程工作,而且提高了軟件系統的可擴展性,因為Java反射機制可以生成任意類型的動態代理類。Java.lang.reflect包中的Proxy類和InvocationHandler接口提供了生成動態代理類的能力。 ? ? 先說說Proxy類,它就是一個動態代理類,最終返回Proxy這個動態代理類所代理的接口類對象,使用的就是Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 這個方法。它有三個參數: - ClassLoader loader----指定被代理對象的類加載器 - Class[] Interfaces----指定被代理對象所實現的接口 - InvocationHandler h----指定需要調用的InvocationHandler對象 ? ?實現InVocationHandler接口,必須實現invoke()方法,該方法就是Proxy這個動態代理類所代理的接口類的抽象方法的真實實現。它有三個參數: - Object proxy-----代理類對象 - Method method-----被代理對象的方法(這里不是接口的抽象方法了,是具體的實現類中的方法) - Object[] args-----該方法的參數數組 ? ? JDK中具體的動態代理類是怎么產生的呢? ? ? 1. ? 產生代理類$Proxy0類 ? ? 執行了Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 將產生$Proxy0類,它繼承Proxy對象,并根據第二個參數,實現了被代理類的所有接口,自然就可以生成接口要實現的所有方法了(這時候會重寫hashcode,toString和equals三個方法),但是還沒有具體的實現體; ? ? 2. ? 將代理類$Proxy0類加載到JVM中 ? ? 這時候是根據Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第一個參數----就是被代理類的類加載器,把當前的代理類加載到JVM中; ? ? 3. ? 創建代理類$Proxy0類的對象 ? ? 調用的$Proxy0類的$Proxy0(InvocationHandler)構造函數,生成$Proxy0類的對象。參數就是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第三個參數。這個參數就是我們自己實現的InvocationHandler對象,我們知道InvocationHandler對象中組合加入了代理類所代理的接口類的實現類;所以,$Proxy0對象調用所有要實現的接口的方法,都會調用InvocationHandler對象的invoke()方法實現。 ? ? 簡單的說了一下JDK動態代理的實現原理。下面我們用代碼把上面的例子實現一下: ? ? 代碼結構圖: ![](https://box.kancloud.cn/2016-02-18_56c53c48c00e1.jpg) ? ? 其中【com.bjpowernode.pattern.explorer.doc包】 OfficeSoftWare.java ~~~ package com.bjpowernode.pattern.explorer.doc; /** * Office軟件接口 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午08:09:55 */ public interface OfficeSoftWare { /** * 打開文件 * @param filePath 文件路徑 */ public void openFile(String filePath); /** * 保存文件 * @param filePath 文件路徑 */ public void saveFile(String filePath); //其他功能... } ~~~ WinWord.java ~~~ package com.bjpowernode.pattern.explorer.doc; /** * WinWord軟件 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午09:01:54 */ public class WinWord implements OfficeSoftWare { /** * 打開文件 * @param filePath 文件路徑 */ @Override public void openFile(String filePath) { System.out.println("打開文檔 "+filePath); } /** * 保存文件 * @param filePath 文件路徑 */ @Override public void saveFile(String filePath) { System.out.println("保存文檔 "+filePath); } /** * 返回名稱 * @return */ @Override public String toString() { return "WinWord軟件"; } } ~~~ 【com.bjpowernode.pattern.explorer.image】包: ImageSoftWare.java ~~~ package com.bjpowernode.pattern.explorer.image; /** * 圖片顯示軟件接口 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午08:08:13 */ public interface ImageSoftWare { /** * 顯示圖片 * @param imgPath 圖片路徑 */ public void viewImg(String imgPath); /** * 刪除圖片 * @param imgPath 圖片路徑 */ public void delImg(String imgPath); //其他功能... } ~~~ ImageView.java ~~~ package com.bjpowernode.pattern.explorer.image; /** * Windows 圖片查看器 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午09:03:23 */ public class ImageView implements ImageSoftWare { /** * 返回軟件名稱 * @return */ @Override public String toString() { return "Windows圖片查看器"; } /** * 刪除圖片 * @param imgPath 圖片路徑 */ @Override public void delImg(String imgPath) { System.out.println("刪除圖片 "+imgPath); } /** * 顯示圖片 * @param imgPath 圖片路徑 */ @Override public void viewImg(String imgPath) { System.out.println("顯示圖片 "+imgPath); } } ~~~ 【com.bjpowernode.pattern.explorer.music】包: MusicSoftWare.java ~~~ package com.bjpowernode.pattern.explorer.music; /** * 音樂軟件接口 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午08:16:43 */ public interface MusicSoftWare { /** * 加載歌曲 * @param songPath 歌曲路徑 */ public void loadSong(String songPath); /** * 播放歌曲 * @param songPath */ public void playSong(String songPath); //其他功能... } ~~~ QQMusicPlayer.java ~~~ package com.bjpowernode.pattern.explorer.music; /** * QQ音樂播放器 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午09:00:25 */ public class QQMusicPlayer implements MusicSoftWare { /** * 加載歌曲 * @param songPath 歌曲路徑 */ @Override public void loadSong(String songPath) { System.out.println("加載歌曲 "+songPath); } /** * 播放歌曲 * @param songPath */ @Override public void playSong(String songPath) { System.out.println("播放歌曲 "+songPath); } /** * 返回名稱 * @return */ @Override public String toString() { return "QQ音樂播放器"; } } ~~~ TTPlayer.java ~~~ package com.bjpowernode.pattern.explorer.music; /** * 千千靜聽播放器 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-8 下午09:03:21 */ public class TTPlayer implements MusicSoftWare { /** * 加載歌曲 * @param songPath 歌曲路徑 */ @Override public void loadSong(String songPath) { System.out.println("加載歌曲 "+songPath); } /** * 播放歌曲 * @param songPath */ @Override public void playSong(String songPath) { System.out.println("播放歌曲 "+songPath); } /** * 返回名稱 * @return */ @Override public String toString() { return "千千靜聽播放器"; } } ~~~ 【com.bjpowernode.pattern.explorer】包: ExplorerHandler.java ~~~ package com.bjpowernode.pattern.explorer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * jdk動態代理代理類 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-9 下午02:46:03 */ public class ExplorerHandler implements InvocationHandler{ /** * 目標對象 */ private Object tagObj = null; /** * 通過反射,獲取目標對象的代理對象 * @param tagObj 目標對象 * @return */ public Object newProxyInstance(Object tagObj){ this.tagObj = tagObj; return Proxy.newProxyInstance(tagObj.getClass().getClassLoader(), tagObj.getClass().getInterfaces(), this); } /** * 通過代理對象,調用方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("\n---->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); //獲取文檔類型 String fileType = args[0].toString().substring(args[0].toString().lastIndexOf(".")+1); System.out.println("您正在操作的文檔類型為:【" + fileType + "】,需要用【" + tagObj.toString() + "】打開"); System.out.print("執行操作--->>>"); //調用方法,并獲取執行結果 Object res = method.invoke(tagObj, args); //返回結果返回值 return res; } } ~~~ Client.java ~~~ package com.bjpowernode.pattern.explorer; import com.bjpowernode.pattern.explorer.doc.OfficeSoftWare; import com.bjpowernode.pattern.explorer.doc.WinWord; import com.bjpowernode.pattern.explorer.image.ImageSoftWare; import com.bjpowernode.pattern.explorer.image.ImageView; import com.bjpowernode.pattern.explorer.music.MusicSoftWare; import com.bjpowernode.pattern.explorer.music.QQMusicPlayer; import com.bjpowernode.pattern.explorer.music.TTPlayer; /** * 客戶端測試動態代理 * * @author : Longxuan * @group : tgb8 * @Version : 1.00 * @Date : 2013-7-9 下午02:45:06 */ public class Client { public static void main(String[] args) { //實例化一個jdk動態代理代理對象 ExplorerHandler explorer = new ExplorerHandler(); //實例化一個window圖片查看器的代理對象 ImageSoftWare isw = (ImageSoftWare) explorer.newProxyInstance(new ImageView()); //通過代理對象,執行顯示圖片 isw.viewImg("1.jpg"); //實例化一個Word的代理對象 OfficeSoftWare osw = (OfficeSoftWare) explorer.newProxyInstance(new WinWord()); //通過代理,執行顯示圖片 osw.openFile("驗收標準V3.1.docx"); //實例化一個QQ音樂播放器的代理對象 MusicSoftWare msw = (MusicSoftWare) explorer.newProxyInstance(new QQMusicPlayer()); //通過代理對象,執行加載歌曲 msw.loadSong("我會很誠實.mp3"); System.out.println("\n---->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); System.out.println("切換音樂默認程序為【 千千靜聽】"); //實例化一個千千靜聽的代理對象 msw = (MusicSoftWare) explorer.newProxyInstance(new TTPlayer()); //通過代理對象,執行播放歌曲 msw.playSong("我會很誠實.mp3"); } } ~~~ 運行結果: ![](https://box.kancloud.cn/2016-02-18_56c53c48d4cad.jpg) ? ? 有了動態代理,在面對100個不同接口時,不用再像靜態代理中編寫100個特定的代理類。正如上面剛剛說過的,在動態代理模式中,只有一個動態代理類,每一個具體的代理對象都是在運行期生成的。這樣不光節省了編碼時間,最重要的是減少了維護的工作量和難度。比如就像例子中的,我需要在執行代碼前,統一有一個操作(檢驗操作的文件類型),只要在代理類的invoke方法中編寫一遍就可以了,而在靜態代理中,需要給每個代理類都需要編寫這段代碼。在后期的更改中,也需要對每個代理類修改。現在換成動態代理,只需改一處即可。時間少,效率高,真是程序員必備之“良藥”呀! ? ? 簡單的介紹了一下動態代理,如果想有更為詳細的了解,請移步《[Java 動態代理機制分析及擴展,第 1 部分](http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/)》 和《[Java 動態代理機制分析及擴展,第 2 部分](http://www.ibm.com/developerworks/cn/java/j-lo-proxy2/)》
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看