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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

动态代理设计模式

發布時間:2024/4/13 asp.net 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态代理设计模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這個時候講一下動態的代理,動態和靜態到底有什么區別呢,其實剛才我已經詳細給大家說一下,靜態代理需要生成目標代理對象,動態代理是不需要生成目標代理對象,如果你們用動態的話,就不會有UserServiceProxy這一層了,這一層是在內存里面動態虛擬出來的,所以給你們講一下,你們也知道,動態代理核心是通過JDK動態代理和CGLIB這個方式進行實現的,那這個時候我再回顧一遍,JDK動態代理是采用反射虛擬生成,CGLIB是基于ASM字節碼技術虛擬生成代理類,這我們講一下,這個代碼我就不去寫了,寫的話就比較浪費時間,核心就講事務里面去,動態代理我就不細說了,動態代理是不需要生成代理類對象的,那么怎么做呢,第一種方式是JDK動態代理方式,底層是采用反射的機制,這段代碼我們來講一下 package com.learn.proxy001;import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy;import com.learn.service.MemberService; import com.learn.service.UserService; import com.learn.service.impl.MemberServiceImpl; import com.learn.service.impl.UserServiceImpl;/*** 每次生成動態代理類對象時,實現了InvocationHandler接口的調用處理器對象* 實現動態代理的時候都需要實現這樣的一個接口* 實現接口它是干嘛用的呢* * @author Leon.Sun**/ public class InvocationHandlerImpl implements InvocationHandler {/*** 首先要把這樣的一個目標代理對象傳進來* */private Object target;// 這其實業務實現類對象,用來調用具體的業務方法// 通過構造函數傳入目標對象public InvocationHandlerImpl(Object target) {this.target = target;}/*** 在實現方法之前或之后做一個處理* * 在你方法之前和之后* 做了攔截* 使用JDK* * * */public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;/*** 使用JDK動態代理開啟事務*/System.out.println("使用jdk動態代理 開啟事務");result = method.invoke(target, args);/*** 使用JDK動態代理提交事務*/System.out.println("使用jdk動態代理 提交事務");/*** 這里返回一個result結果*/return result;}/*** 這里我寫了一個main函數* @param args* @throws NoSuchMethodException* @throws SecurityException* @throws InstantiationException* @throws IllegalAccessException* @throws IllegalArgumentException* @throws InvocationTargetException*/public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 被代理對象// IUserDao userDao = new UserDao();/*** 這里寫一個UserService的實現* 在這里為就可以拿到UserService* 拿到UserService之后* 然后在這邊怎么處理呢* * 我只要把我們的目標代理對象傳進去就=行了* 它會自動的在你方法之前之后做這樣的處理* 就是這樣的* 有些人可能沒有學過AOP編程* 沒有學過代理設計模式* 像靜態代理是需要有一個接口的* 什么接口呢* 你必須有個接口* CGLIB可能不需要你有這個接口* 這個大體我說一下* 后面我們使用Spring事務的時候比這個簡單* 我們在AOP的基礎上使用事務* 就方便多了* 如果你真的需要寫的情況下* 那這些代碼都要寫的* 這里可以傳入任何的類* 這樣就可以在方法之前和之后做處理的* 這個就比較簡單* 你們注意看* 靜態代理是有這么一個靜態代理類對象的* 他每一個都要這么去寫的* 記住動態代理是不需要寫目標代理對象的* 是沒有寫代理對象的* 而且你們要記住啊* 我這里可以支持很多方法和任何接口* 都可以做一個這樣的代理的* * */UserService userService = new UserServiceImpl(); // InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userService);/*** ClassLoader有多少人了解過* 可能不了解ClassLoader是干嘛用的* 他其實可以加載類的信息* 加載到JVM的內存里面去* 這個我記得是昨天剛講了* 這個我相信你們都記得* 熱部署其實就是通過ClassLoader進行實現的* 動態的把最新的字節碼文件讀取到JVM里面去* 就是這樣的一個原理*/ // ClassLoader loader = userService.getClass().getClassLoader(); // Class<?>[] interfaces = userService.getClass().getInterfaces();// 主要裝載器、一組接口及調用處理動態代理實例/*** 這里我們可以強轉一下UserService*/ // UserService newProxyInstance = (UserService) Proxy.newProxyInstance(loader, interfaces, // invocationHandlerImpl);/*** 然后ADD方法就OK了* 不過這個例子非常簡單* */ // newProxyInstance.add();/*** new一個MemberServiceImpl* 是不是這樣的* 注意這里不需要代理對象* 我們這里沒有封裝* 正常只需要傳一個類進來* * */MemberService memberServiceImpl = new MemberServiceImpl();InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(memberServiceImpl);ClassLoader loader = memberServiceImpl.getClass().getClassLoader();Class<?>[] interfaces = memberServiceImpl.getClass().getInterfaces();// 主要裝載器、一組接口及調用處理動態代理實例MemberService newProxyInstance = (MemberService) Proxy.newProxyInstance(loader, interfaces,invocationHandlerImpl);/*** JDK動態代理開啟事務* 這里是方法業務* 在方法之前和之后做一些業務處理* 只要任何有接口的類* 我這里是寫死的* 因為只是講DEMO* 還有CGLIB就先不講了* 因為時間有限* 也是一樣的道理* 也是比較簡單* 只不過底層用的ASM* 就是通過字節碼技術生成一個代理類的* 目標類寫死沒關系的* 這只是舉個列子* */newProxyInstance.memberAdd();} } package com.learn.service;public interface MemberService {public void memberAdd(); } package com.learn.service.impl;import com.learn.service.MemberService;/*** 如果我們要實現靜態代理的話* 我們就需要再寫一個代理類* 那就寫的很麻煩* * * @author Leon.Sun**/ public class MemberServiceImpl implements MemberService {public void memberAdd() {System.out.println("memberAdd");}} 動態代理 什么是動態代理 1.代理對象,不需要實現接口 2.代理對象的生成,是利用JDK的API,動態的在內存中構建代理對象(需要我們指定創建代理對象/目標對象實現的接口的類型) 3.動態代理也叫做:JDK代理,接口代理 JDK動態代理 1)原理:是根據類加載器和接口創建代理類(此代理類是接口的實現類,所以必須使用接口 面向接口生成代理, 位于java.lang.reflect包下) 2)實現方式: 1. 通過實現InvocationHandler接口創建自己的調用處理器 IvocationHandler handler = new InvocationHandlerImpl(…); 2. 通過為Proxy類指定ClassLoader對象和一組interface創建動態代理類 Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…}); 3. 通過反射機制獲取動態代理類的構造函數,其參數類型是調用處理器接口類型 Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class}); 4. 通過構造函數創建代理類實例,此時需將調用處理器對象作為參數被傳入 Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler)); 缺點:jdk動態代理,必須是面向接口,目標業務類必須實現接口 CGLIB動態代理 原理:利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。 什么是CGLIB動態代理 使用cglib[Code Generation Library]實現動態代理,并不要求委托類必須實現接口,底層采用asm字節碼生成框架生成代理類的字節碼 CGLIB動態代理與JDK動態區別 java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。 而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。 Spring中。 1、如果目標對象實現了接口,默認情況下會采用JDK的動態代理實現AOP 2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP 3、如果目標對象沒有實現了接口,必須采用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換 JDK動態代理只能對實現了接口的類生成代理,而不能針對類 。 CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法 。 因為是繼承,所以該類或方法最好不要聲明成final ,final可以阻止繼承和多態。

?

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的动态代理设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。