1. 程式人生 > >黑馬程式設計師——動態代理詳解

黑馬程式設計師——動態代理詳解

/*
 * 動態代理的作用
 * 通過反射呼叫代理物件,讓其幫我們實現一些非常頻繁的操作,如:許可權校驗和日誌記錄
 * 代理的實現原理:
 * 在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler介面
 * 通過使用這個類和介面就可以生成動態代理物件。這裡只能針對介面實現代理,後期cglib可以實現類的代理
 * 代理的實現過程:
 * 既然是代理,顧名思義,就是代替某個類或介面去實現某個功能,也就是說,我代理了你,我就具備了你的功能。
 * 怎麼才能具有其他類或介面的功能呢:要麼是繼承自類,要麼是實現介面。而我們已經知道,此處只能代理介面。
 * 所以在造該代理物件時,肯定是讓其實現了被代理的介面。
 * 而實現了介面還只是第一步,我還要提供一些特有的功能
 * 所以再建立完動態代理物件以後至少要實現這兩個目的:實現被代理的功能、並提供特殊功能。
 * 
 * 具體步驟:
 * 首先由Proxy類的靜態方法newProxyInstance建立動態代理物件
 * public static Object newProxyInstance
 * (ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
 * 而要建立該物件,需要3個引數
 * ClassLoader loader:定義了由哪個ClassLoader物件來對生成的代理物件進行載入
 * Class<?>[] interfaces:表示的是我將要給我需要代理的物件提供一組什麼介面
 * InvocationHandler h:既然一個指明瞭載入器,一個指明瞭介面,那麼這個就是具體實現功能的方法了。
 * 
 * InvocationHandler物件,表示的是當我這個動態代理物件在呼叫方法的時候,會關聯到哪一個InvocationHandler物件上
 * 每一個動態代理類都必須要實現InvocationHandler這個介面,當我們通過代理物件呼叫一個方法的時候,
 * 這個方法的呼叫就會被轉發為由InvocationHandler這個介面的invoke 方法來進行呼叫
 * public Object invoke(Object proxy, Method method, Object[] args)
 * InvocationHandler介面中invoke方法的三個引數:
 * proxy:代表動態代理物件
 * method:代表正在執行的方法
 * args:代表呼叫目標方法時傳入的實參
 * 由此可知,實際在實現InvocationHandler介面重寫invoke方法時,所需要的三個引數都不要我們給出
 */

需求:用動態代理實現使用者註冊登入的校驗和記錄

實現:

首先定義使用者登入註冊介面

public interface StudentDao {

	public abstract void login();
	
	public abstract void regist();
}
實現介面類
public class StudentDaoImpl implements StudentDao {

	@Override
	public void login() {
		System.out.println("登入功能");
	}

	@Override
	public void regist() {
		System.out.println("註冊功能");
	}

}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/*
 * 由於該物件要重寫的方法中會呼叫代理物件的方法,所以需要把被代理的目標物件以引數的方法傳入
 * 然後使用反射呼叫目標物件的方法
 */
public class MyInvocationHandler implements InvocationHandler {

	private Object target;	//目標物件
	public MyInvocationHandler(Object target){
		this.target = target;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//代理要提供的特殊功能
		System.out.println("許可權校驗");
		
		//通過反射執行目標物件的方法
		method.invoke(target, args);
		
		//代理要提供的特殊功能
		System.out.println("日誌記錄");
		return null;//如果底層方法返回型別為 void,則該呼叫返回 null
	}

}

建立動態代理物件並實現功能

import java.lang.reflect.Proxy;

/*
 分析:
 登入註冊屬於使用者的擴充套件功能,用介面實現
 然後重寫抽象方法,實現介面
 建立實現InvocationHandler介面的物件作為Proxy的引數使用(其實,底層方法的呼叫即特殊功能的實現都是通過該物件實現的)
 由Proxy的靜態方法建立動態代理物件,由於返回值是Object所以需要向下轉型
 */
public class ProxyDemo {

	public static void main(String[] args) {
		// 建立被代理物件
		StudentDao st = new StudentDaoImpl();
		// 建立實現InvocationHandler介面的物件
		MyInvocationHandler mi = new MyInvocationHandler(st);
		// 建立動態代理物件
		StudentDao proxy = (StudentDao) Proxy.newProxyInstance(st.getClass()
				.getClassLoader(), st.getClass().getInterfaces(), mi);
		//用動態代理物件呼叫方法
		proxy.login();
		proxy.regist();
	}
}





相關推薦

黑馬程式設計師——動態代理

/*  * 動態代理的作用  * 通過反射呼叫代理物件,讓其幫我們實現一些非常頻繁的操作,如:許可權校驗和日誌記錄  * 代理的實現原理:  * 在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler介面  * 通

黑馬程式設計師————動態代理

public class Demo {public static void main(String[] args) throws Exception {// 不使用代理/** IStudent stu = new Student(); stu.coding();*/// 使用代理// 以下方法的呼叫,獲取了一

黑馬程式設計師 動態代理

  一,什麼是動態代理?     動態代理就是使用反射動態的實現一個類的載入從而實現動態例項化一個類的物件的效果。 二,怎樣實現動態代理?     1,首先讓代理類實現InvocationHandler介面,此介面中的invoke方法如下:              O

黑馬程式設計師- 動態代理 ,介面 ,抽象類

包含抽象方法的類稱為抽象類,但並不意味著抽象類中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變數和普通的成員方法。注意,抽象類和普通類的主要有三點區別:   1)抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承,

黑馬程式設計師——常用API之Object、Scanner、String

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ------- A:Object類 Object類是所有類的根類,其所有的方法為所有類所共有,所以很多類的基本功能都是依賴於Object實現的。 如: 無參構造方法(Object只有無參

黑馬程式設計師-----動態代理Proxy

public class ProxyDemo3 { public static void main(String[] args) { //寫一個Collection集合的動態代理 //使用Proxy的newProxyInstance方法直接建立代理物件 Collection proxyCol

黑馬程式設計師-----高新技術-----動態代理

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- 在學習Spring的時候,我們知道S

動態代理

font output 接口 col tle 訪問 AC 學習 stat 動態代理詳解 ? ?動態代理它可以直接給某一個目標對象生成一個代理對象,而不需要代理類存在。? ? 動態代理與代理模式原理是一樣的,只是它沒有具體的代理類,直接通過反射生成了一個代理對象。? ? 動

Java 動態代理

部落格原文:http://laijianfeng.org/2018/12/Java-動態代理詳解/ 動態代理在Java中有著廣泛的應用,比如Spring AOP、Hibernate資料查詢、測試框架的後端mock、RPC遠端呼叫、Java註解物件獲取、日誌、使用者鑑權、

JDK動態代理(原始碼剖析)

一、什麼是代理? 代理是一種常用的設計模式,其目的就是為其他物件提供一個代理以控制對某個物件的訪問。代理類負責為委託類預處理訊息,過濾訊息並轉發訊息,以及進行訊息被委託類執行後的後續處理。代理模式UML圖:簡單結構示意圖:為了保持行為的一致性,代理類和委託類通常

Java程式設計師——大牛Nginx系列—nginx變數實現原理(上)

上一篇(Java程式設計師——大牛詳解Nginx系列—Ngx中的變數)主要描述的是變數的使用,所以沒涉及任何程式碼,而這一篇主要描述變數的實現原理,避免不了會涉及到一些底層程式碼,對於不瞭解c語言的同學讀起來可能會有點吃力,這部分同學可以嘗試一下兩篇結合著讀,比如先讀一個知識點的用法,然後再回到這篇

Java程式設計師——大牛Nginx系列—Ngx中的變數

本文來自網路, 在計算機語言中,變數是用來儲存和表示資料的,但不同的語言表示變數的方式不同,像java語言會把變數抽象成各種型別,並且每種型別都會用一個特殊的符號表示,比如表示一個整數需要這樣:      int age= 25;  

java動態代理,並用動態代理和註解實現日誌記錄功能

動態代理的概念       動態代理是程式在執行過程中自動建立一個代理物件來代替被代理的物件去執行相應的操作,例如, 我們有一個已經投入執行的專案中有一個使用者DAO類UserDao用來對User物件進行資料庫的增刪改查操作,但是有一天,要求在對使用者的增刪改查操作時記錄相

jdk動態代理 和 CGLIB動態代理

1. 靜態代理模式 //目標介面 public interface IDoSomething { public void doSomething(); }//目標物件 public class DoSomething implements IDoSomething{

java jdk動態代理

        }       }       methods.add(generateStaticInitializer());   }   catch(IOException ioexception)   {       throw new InternalError("unexpected I/O

JDK動態代理

今年企業對Java開發的市場需求,你看懂了嗎? >>>   

基於SpringBoot實現AOP+jdk/CGlib動態代理

動態代理是一種設計模式。在Spring中,有倆種方式可以實現動態代理--JDK動態代理和CGLIB動態代理。 JDK動態代理 首先定義一個人的介面: public interface Person { void study(); } 然後接上一個Student class public class S

黑馬程式設計師-----Java基礎-----集合框架

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- 經常會看到程式中使用了記錄集,常用的有

黑馬程式設計師_java高新技術之動態代理

                                 ----------- android培訓、java培訓、java學習型技術部落格、期待與您交流! --------- 一.代理物件存在的價值:當.class檔案 被類載入器載入 到記憶體 形成Class物件

黑馬程式設計師--高新技術之動態代理

                                ------- android培訓、java培訓、期待與您交流! ---------- 一、關於動態代理的一些基本概念     在程式設計中,很多時候我們要為已存在的多個具有相同介面的目標類的各個     方法