詳解:設計模式之-代理設計

分享一波:程序員賺外快-必看的巔峰干貨

概念

通過代理控制對象的訪問,可以詳細訪問某個對象的方法,在這個方法調用處理,或調用后處理(類似于AOP)。

代理設計模式應用場景:AOP、權限控制、事務

常見代理的分類有:靜態代理,動態代理(JDK動態代理,Cglib等)

注意:本文所指的“代理”為設計模式中的“代理設計模式”,跟正向、反向代理并非一個概念,不要混淆。
靜態代理

由程序員創建或工具生成代理類的源碼,再編譯代理類。所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委托類的關系在運行前就確定了。

public interface IUserDao {
void save();
}

public class UserDao implements IUserDao {
public void save() {
System.out.println(“已經保存數據…”);
}
}

/**

  • 代理類
    */
    public class UserDaoProxy implements IUserDao {
    private IUserDao target;

    public UserDaoProxy(IUserDao iuserDao) {
    this.target = iuserDao;
    }

    public void save() {
    System.out.println(“開啟事物…”);
    target.save();
    System.out.println(“關閉事物…”);
    }

}

靜態代理需要每個被代理類都有一個代理類,因此代碼量較多,實際開發中非必須情況盡量少用。
動態代理
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動態代理,必須是面向接口,目標業務類必須實現接口

public class InvocationHandlerImpl implements InvocationHandler {

/** 目標代理對象 */
private Object target;public InvocationHandlerImpl(Object target) {this.target = target;
}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 反射執行方法Object invoke = method.invoke(target, args);return invoke;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 被代理對象IUserDao userDao = new UserDao();InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);ClassLoader loader = userDao.getClass().getClassLoader();Class<?>[] interfaces = userDao.getClass().getInterfaces();// 主要裝載器、一組接口及調用處理動態代理實例IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);newProxyInstance.save();
}

}

Cglib動態代理

原理:利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

使用cglib[Code Generation Library]實現動態代理,并不要求委托類必須實現接口,底層采用asm字節碼生成框架生成代理類的字節碼

引入依賴:

org.apache.commons commons-lang3 3.8.1 cglib cglib 3.1

創建代理:

public class CglibProxy implements MethodInterceptor {

/** 代理對象 */
private Object target;public Object getInstance(Object target) {// 固定代碼,創建訪問對象this.target = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();
}public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object invoke = methodProxy.invoke(target, args);return invoke;
}public static void main(String[] args) {CglibProxy cglibProxy = new CglibProxy();UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());userDao.save();
}

}

Cglib和jdk動態代理的區別

java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。

而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

Spring中。

1、如果目標對象實現了接口,默認情況下會采用JDK的動態代理實現AOP

2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP

3、如果目標對象沒有實現了接口,必須采用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

JDK動態代理只能對實現了接口的類生成代理,而不能針對類 。

CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法 。

因為是繼承,所以該類或方法最好不要聲明成final ,final可以阻止繼承和多態。

分享一波:程序員賺外快-必看的巔峰干貨

如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程

請關注微信公眾號:HB荷包
在這里插入圖片描述
一個能讓你學習技術和賺錢方法的公眾號,持續更新

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/537045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537045.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537045.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【實時+排重】擺脫渠道統計刷量作弊行為

如今的渠道統計不僅要看精準度&#xff0c;更要看數據的真實性。 對App的推廣業務而言&#xff0c;渠道監測和統計是必不可少的環節&#xff0c;不論以什么形式開展推廣&#xff0c;終究都要具體落實到App的安裝量、激活量等指標上。但在如今數據刷量和作假行為橫行的背景下&am…

python清空idle的內容_Python IDLE清空窗口的實例

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技術人對外發布原創技術內容的最大平臺&…

詳解:設計模式之-單例設計模式

分享一波:程序員賺外快-必看的巔峰干貨 前言 近期預計1-2周左右會更新設計模式專題文章。 單例設計模式&#xff1a;保證在一個JVM中&#xff0c;只能存在一個實例。 應用場景&#xff1a;Servlet&#xff0c;Spring IOC&#xff0c;線程池&#xff0c;連接池&#xff0c;S…

rabbitmq可靠性投遞_阿里Java研發二面:了解RabbitMQ?說說RabbitMQ可靠性投遞

上期寫到高并發下RabbitMq消息中間件你應該介么玩今天給小伙伴說說&#xff01;有自己看法的也可以在評論區留言探討&#xff0c;也可以轉發關注下我以后會長期分享&#xff01;目錄&#xff1a;確保消息發送到RabbitMQ服務器確保消息被正確的路由確保消息在隊列正確地存儲確保…

IBM發布Open Liberty 18.0.0.4,支持MicroProfile 2.1和反應性擴展框架

IBM在2018年第四季度發布的Open Liberty 18.0.0.4提供了對MicroProfile 2.1、反應性擴展框架和連接池指標的全面支持。根據發布說明&#xff1a;Open Liberty現在對JAX-RS 2.1進行了反應性擴展&#xff0c;這樣你就可以使用來自Apache CXF和Jersey的提供程序。在ops方面&#x…

b700a怎么連藍牙_233621藍牙2.1無線音箱B700A小測

隨著藍牙技術的發展&#xff0c;使用藍牙的相關產品也越來越多&#xff0c;各種藍牙耳機、藍牙鍵盤、藍牙鼠標都讓我們的外設擺脫了線材的束縛。小編之前也介紹過一款便攜藍牙音箱&#xff0c;也評測過一款藍牙耳機&#xff0c;而今天拿到的是一款采用藍牙2.1技術&#xff0c;造…

詳解:設計模式之-適配器模式

分享一波:程序員賺外快-必看的巔峰干貨 簡介 在設計模式中&#xff0c;適配器模式有時候也稱包裝樣式或者包裝。將一個類的接口轉接成用戶所期待的。一個適配使得因接口不兼容而不能在一起工作的類工作在一起&#xff0c;做法是將類自己的接口包裹在一個已存在的類中。 分類 …

excel 中編程:vba 入門

2019獨角獸企業重金招聘Python工程師標準>>> 1. 打開編程環境&#xff1a; altF11 打開開發環境 注意需要啟動宏&#xff0c;不然不能執行自定義的程序&#xff0c;保存后文件的后綴應該是&#xff1a;.xlsm 選擇一個 sheet 或一個模塊&#xff0c;右鍵查看代碼&…

android 快傳 源碼_最新安卓仿茄子快傳APP源碼包括服務端源碼Android開發快傳類項目源碼全套...

適使用范圍&#xff1a; 安卓APP茄子快傳源碼 Android項目源碼相似茄子快傳的快傳項目包括服務端運行環境&#xff1a; Android app源碼詳細&#xff1a;本項目是一個基于安卓的相似茄子快傳的項目源碼&#xff0c;包括安卓用戶端源碼&#xff0c;java的PC用戶端和PHP 的web網…

詳解:設計模式之-策略設計模式

分享一波:程序員賺外快-必看的巔峰干貨 什么是策略模式 定義一系列的算法&#xff0c;并將每一個算法單獨進行封裝&#xff0c;而且使它們可以相互替換&#xff0c;從而達到傳遞不同參數而執行不同算法的結果。 策略模式讓算法獨立于使用它的客戶而獨立變化 策略模式應用場…

mysql decode語句_MySQL復制問題的分析

s這是學習筆記的第 2031 篇文章最近有個業務的MySQL復制問題還是比較多&#xff0c;做了事務降維之后&#xff0c;把一些敏感操作和線上環境隔離起來&#xff0c;整體的效果好了許多&#xff0c;不過今天在外面的時候&#xff0c;又收到一條報警短信&#xff0c;讓我心里咯噔一…

jvm形象簡介之一看就懂

分享一波:程序員賺外快-必看的巔峰干貨 據 JVM 規范&#xff0c;JVM 內存結構共分為虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。這里的java內存結構與前面所述的Java內存模型是兩個概念&#xff0c;不可以混淆。 堆 java堆是java虛擬機所管理的內存中最大的一塊…

MZOJ 1345 hero

一道寬搜模版題,可寫錯了兩個地方的我只得了56(掩面痛哭) http://10.37.2.111/problem.php?id1345 先看看正確的 #include <bits/stdc.h> #define read read() #define up(i,l,r) for(int i l; i<r; i) using namespace std;int read {int x 0; char ch getchar()…

opencv拖動進度條_OpenCV GUI基本操作,回調函數,進度條,裁剪圖像等-阿里云開發者社區...

代碼為轉載&#xff0c;出處找不到了&#xff0c;不貼了工具條進度條&#xff1a;// ConvertColor.cpp : 定義控制臺應用程序的入口點。//#include "stdafx.h"#include #include #include #pragma comment(lib,"opencv_core2410d.lib")#pragma comment(lib…

區間DP初探 P1880 [NOI1995]石子合并

https://www.luogu.org/problemnew/show/P1880 區間dp,顧名思義,是以區間為階段的一種線性dp的拓展 狀態常定義為$f[i][j]$,表示區間[i,j]的某種解; 通常先枚舉區間長度,再枚舉左端點,最后枚舉斷點(k) 石子合并便是一道經典的區間dp #include <bits/stdc.h> #define read…

jvm詳解 - 新生代與老年代

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 Java 中的堆是 JVM 所管理的最大的一塊內存空間&#xff0c;主要用于存放各種類的實例對象。 在 Java 中&#xff0c;堆被劃分成兩個不同的區…

pymysql建表_Python數據庫操作,針對pymysql 和 MYSQL數據庫

此文將以MYSQL數據庫做為例子,pymysql庫作為驅動進行學習安裝MYSQL數據庫與pymysql第三方庫安裝pymysql庫不多做敘述安裝navicat for mysql,此程序用來管理MYSQL數據庫注意: 連接過程中可能會出現1251錯誤解決辦法,在cmd命令下登錄mysql后輸入:ALTER USER rootlocalhost IDENTI…

從0到1使用VUE-CLI3開發實戰(五):模塊化VUEX及使用vuetify

小肆前幾天發了一篇2019年Vue精品開源項目庫的匯總&#xff0c;今天小肆要使用的是在UI組件中排行第三的Vuetify。vuetify介紹 Vuetify是一個漸進式的框架&#xff0c;完全根據Material Design規范開發&#xff0c;一共擁有80多個組件&#xff0c;對移動端支持非常好。 支持SSR…

詳解垃圾回收算法

分享一波:程序員賺外快-必看的巔峰干貨 標記清除算法 概念 該算法有兩個階段。 標記階段&#xff1a;找到所有可訪問的對象&#xff0c;做個標記。 清除階段&#xff1a;遍歷堆&#xff0c;把未被標記的對象回收 缺點&#xff1a;會產生碎片&#xff0c;不夠連貫 應用場景…

智能情緒分析技術_石化緣推薦:煉化企業智能機器人巡檢技術應用前景分析!...

本期內容由湖南天一奧星泵業有限公司冠名煉化企業智能機器人巡檢技術應用前景分析王國彤1,孫秉才2,儲勝利2,宋亞敏1(1.中國石油天然氣股份有限公司大連石化分公司&#xff0c;遼寧省大連市&#xff1b;2.中國石油集團安全環保技術研究院有限公司&#xff0c;北京市)摘要&#x…