一、代理模式的作用 將主要業務與次要業務進行松耦合的組裝 二、代理模式本質 監控行為的特征 例子: <input type="button" onclick="處理函數"> 三、生活案例 案例:飯前便後要洗手 分析: 1.分析出主要業務和次要業務 【主要業務】:吃飯,上廁所 【次要業務】:洗手 2. ...
一、代理模式的作用
- 將主要業務與次要業務進行松耦合的組裝
二、代理模式本質
- 監控行為的特征
例子:
<input type="button" onclick="處理函數">
三、生活案例
案例:飯前便後要洗手
分析:
1.分析出主要業務和次要業務
【主要業務】:吃飯,上廁所
【次要業務】:洗手
2.JDK代理模式實現
2.1、介面角色:定義所有需要被監聽行為
BaseService.java
1 package com.chenyanbin.service; 2 3 /* 4 * 只有需要被監控的行為才有資格在這裡聲明 5 */ 6 public interface BaseService { 7 public void Eat(); 8 public void Wc(); 9 }
2.2、介面實現類:中國人、印度人
Person.java
1 package com.chenyanbin.serviceImpl; 2 3 import com.chenyanbin.service.BaseService; 4 5 public class Person implements BaseService { 6 7 @Override 8 public void Eat() { //主要業務,代理模式要求開發任務只關心主要業務 9 System.out.println("使用筷子吃飯"); 10 } 11 12 @Override 13 public void Wc() { 14 System.out.println("測試地球重力是否存在"); 15 } 16 }
2.3、通知類:1)次要業務進行具體實現 2)通知JVM,當前被攔截的主要業務方法與次要業務方法應該如何綁定執行
Invaction.java
1 package com.chenyanbin.util; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 import com.chenyanbin.service.BaseService; 7 8 public class Invaction implements InvocationHandler { 9 private BaseService obj;// 具體被監控對象 10 11 public Invaction(BaseService param) { 12 this.obj = param; 13 } 14 15 /* 16 * invoke方法:被監控行為將要執行時,會被JVM攔截,被監控行為和行為實現方會被作為參數輸送到invoke 17 * ***通知JVM,這個被攔截方法是如何與當前次要業務方法綁定實現 invoke方法三個參數 小明.Eat();//JVM攔截 18 * Eat方法封裝為Method類型方法 Eat方法運行時所有的實參封裝到Object[] 將負責監控小明的代理對象作為invoke方法第一個參數 19 * 20 */ 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 23 // 0.局部變數,接受主要業務方法執行完畢後返回值 24 Object value; 25 // 1.確認當前被攔截行為 26 String methodName = method.getName(); 27 // 2.根據被攔截行為不同,決定主要業務和次要業務如何綁定執行 28 if ("Eat".equals(methodName)) { // 飯前要洗手 29 Wash();// 洗手 30 value = method.invoke(this.obj, args);// 當前主要業務 31 } else { // 便後洗手 32 value = method.invoke(this.obj, args);// 當前主要業務 33 Wash();// 洗手 34 } 35 return value; //返回被攔截方法 36 } 37 38 // 次要業務 39 public void Wash() { 40 System.out.println("--------洗手--------"); 41 } 42 }
2.4、監控對象(代理對象):1)被監控實例對象 2)需要被監控行為 3)具體通知類實例對象
ProxyFactory.java
1 package com.chenyanbin.util; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 import com.chenyanbin.service.BaseService; 7 8 public class ProxyFactory { 9 /* 10 * JDK動態代理模式下,代理對象的數據類型 應該由監控行為來描述 參數:Class文件,監控類 11 */ 12 public static BaseService build(Class classFile) throws Exception { 13 //1.創建被監控實例對象 14 BaseService obj = (BaseService) classFile.getDeclaredConstructor().newInstance(); 15 //2.創建通知對象 16 InvocationHandler adviser=new Invaction(obj); 17 //3.向JVM申請負責監控obj對象指定行為的監控對象(代理對象) 18 /* 19 * loader:被監控對象隸屬的類文件在記憶體中真實地址 20 * interfaces:被監控對象隸屬的類文件實現介面 21 * h:監控對象發現小明要執行被監控行為,應該由哪一個通知對象進行輔助 22 */ 23 BaseService $proxy=(BaseService)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser); 24 return $proxy; 25 } 26 }
測試類
TestMain.java
1 import com.chenyanbin.service.BaseService; 2 import com.chenyanbin.serviceImpl.Person; 3 import com.chenyanbin.util.ProxyFactory; 4 5 public class TestMain { 6 7 public static void main(String[] args) throws Exception { 8 //mike.Eat(); 9 // Person mike=new Person(); 10 BaseService mike = ProxyFactory.build(Person.class); 11 mike.Eat(); 12 } 13 }
吃飯
上廁所
項目目錄結構