Mybatis代理設計模式(Proxy)與程式設計實現原理

1. 認識代理模式
1.1 模式定義
給某一個物件提供一個代理或佔位符,並由代理物件來控制對原物件的訪問。
代理模式是一種物件結構型模式。在代理模式中引入了一個新的代理物件,代理物件在客戶端物件和目標物件之間起到中介的作用,它去掉客戶不能看到的內容和服務或者增添客戶需要的額外的新服務。
1.2 解決何種問題
將【次要業務】和【主要業務解耦合】。
核心就是代理物件(Proxy)。
1.3次要業務和主要業務
1.3.1 它們之間的區分
次要業務:輔助【主要業務】順利實現。在專案中【次要業務】往往大量重複出現。
主要業務:主要任務。
1.3.2 次要業務對於開發效率影響
- 載入驅動類。【次要業務】
- 建立連線通道。【次要業務】
- 建立資料庫操作物件。【次要業務】
- 推送sql命令道資料庫執行並返回處理結果。【主要業務】
- 銷燬connection,statement,resultSet。【次要業務】
1.4 代理模式的本質
控制物件訪問(行為的監聽)
<input type="button" onclick="fun1">
onclick行為監聽物件(代理物件proxy)對 button 單擊的行為呼叫了fun1方法(InvovationHandler)
1.5 代理模式的組成
- 介面:宣告需要被監聽行為。
- 代理實現類:次要業務實現、將次要業務和主要業務繫結執行。
- 代理物件(監聽物件)
2. 例項講解
2.1 例項業務介紹
飯前便後要洗手
【主要業務】:吃飯、便便。
【次要業務】:洗手。
2.2 具體實現
建立一個介面BaseService
//被監控的行為 public interface BaseService { //吃飯方法 public void eating(String food); //上廁所方法 public void wcing(); }
代理實現類Agent
public class Agent implements InvocationHandler { private BaseService obj;// 被開發人員索要的真實物件 //完成次要業務和主要業務繫結 public Agent(BaseService param) { this.obj = param; } /* *Object proxy:本次負責監聽物件----onclick * *Method method: 被攔截的主要業務方法 * *Object[] params:被攔截的主要業務方法接受的實參 */ @Override public Object invoke(Object proxy, Method method, Object[] params) throws Throwable { //1.讀取被攔截的方法名稱 String methodName = method.getName(); if("eating".equals(methodName)){//飯前要洗手 wash(); method.invoke(obj, params); }else{//便後要洗手 method.invoke(obj, params); wash(); } return null; } //次要業務 private void wash(){ System.out.println("洗手");//解耦合; }
建立介面實現類,Person實現了BaseService中的方法是需要被監聽的方法
public class Person implements BaseService { @Override public void eating(String food) { System.out.println("狼吞虎嚥吃 "+food); } @Override public void wcing() { System.out.println("減體重..."); } }
建立一個代理工廠ProxyFactory
public class ProxyFactory { //扮演一個角色(吃和拉的監聽物件) public static BaseService newInstance(Class classFile) throws InstantiationException, IllegalAccessException{ //0.建立被索要的型別的例項物件 BaseService 小明 = new Person(); //1.擁有一個代理實現類物件 InvocationHandler agent = new Agent(小明);//小明被囚禁到了Agent中 //2.申請/註冊一個對特定行為進行監控物件(代理物件) /* *loader:指向被監控的類檔案在記憶體中真實地址 *interfaces(classArray): 被監控的類所實現的介面,這個介面中宣告的方法,就是需要被監控行為也是主要業務行為名稱 */ Class classArray[]={BaseService.class}; //這個接口裡所有的方法都要被監聽 //建立一個代理監聽物件 BaseService 監聽物件=(BaseService) Proxy.newProxyInstance(Person.class.getClassLoader(), classArray, agent); return監聽物件;//返回的是一個假貨(披著羊皮的狼) 監聽物件 }
測試類
public class TestMain { public static void main(String[] args) throws InstantiationException, IllegalAccessException { //BaseService 小明 = new Person();//醜陋的行為 不受監控的物件 BaseService 小明 = ProxyFactory.newInstance(); 小明.eating("雞"); } }
測試結果
洗手 狼吞虎嚥吃 雞