之動態代理

原文:http://www.jb51.net/article/79565.htm

參考:http://www.jb51.net/article/84659.htm

本文針對java動態代理進行知識點整理,具體內容如下

一. JAVA的動態代理(比較官方說法)
  代理模式是常用的java設計模式,他的特徵是代理類與委託類有同樣的接口,代理類主要負責爲委託類預處 理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。  代理類與委託類之間通常會存在關聯關係,一個代理類的對象與一個委託類的對象關聯,代理類的 對象本身並不真正實現服務,而是通過調用委託類的對象的相關方法,來提  供特定的服務。
  按照代理的創建時期,代理類可以分爲兩種。
  靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。
  動態代理:在程序運行時,運用反射機制動態創建而成。

二. 動態代理實現

  java.lang.reflect.Proxy,
  Proxy 提供用於創建動態代理類和實例的靜態方法.
  newProxyInstance()
  返回一個指定接口的代理類實例,該接口可以將方法調用指派到指定的調用處理程序。

 2.1. Dao接口(提供模擬數據訪問層接口)

1
2
3
4
5
6
7
8
package javaproxy;
/*
 * 定義一個數據訪問層接口
 */
public interface Dao {
 //模擬數據保存
public void save();
}

2.2. DaoImpl類實現類

1
2
3
4
5
6
7
8
9
10
11
package javaproxy;
  
public class DaoImpl implements Dao{
  
 @Override
 public void save() {
  System.out.println("執行一個保存方法。。。。。。。。。。。。");
    
 }
  
}

2.3. 代理處理類

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package javaproxy;
  
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
  
public class DaoHandler implements InvocationHandler{
 private Object obj;
public DaoHandler(Object obj) {
 this.obj=obj;
}
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
   System.out.println("do something before method");//這裏模擬AOP的前置方法
   Object ret = method.invoke(this.obj, args);
   System.out.println("do something after method");//這裏模擬AOP的後置方法
   return ret;
 }
  
}

 2.4. client調用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package javaproxy;
  
import java.lang.reflect.Proxy;
  
public class Client {
    
  public static void main(String[] args) {
   // 元對象(被代理對象)
   DaoImpl daoImpl = new DaoImpl();
    
   // 業務代理類
   DaoHandler daoHandler=new DaoHandler(daoImpl);
    
   Dao dao=(Dao) Proxy.newProxyInstance(daoImpl
    .getClass().getClassLoader(), daoImpl.getClass()
    .getInterfaces(), daoHandler);
    
   dao.save();
  
 }
}

2. 5. 結果

3. 模擬Mybatis中的代理實現

3.1. MapperProxy類

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package javaproxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class MapperProxy implements InvocationHandler {
 @SuppressWarnings("unchecked")
 /*
  * 這裏通過靜態方法得到實現類的對象
  *
  * @param:接口
  *
  * @param:用sqlsession執行方法
  *
  * @return: 返回代理對像
  */
 public static <T> T newMapperProxy(Class<T> mapperInterface,
   Object sqlSession) {
  ClassLoader classLoader = mapperInterface.getClassLoader();
  Class<?>[] interfaces = new Class[] { mapperInterface };
  MapperProxy proxy = new MapperProxy();
  return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
 }
 
 /*
  * (non-Javadoc)
  *
  * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
  * java.lang.reflect.Method, java.lang.Object[])
  *
  * @param:代理對象
  *
  * @param:方法通過方法名字找到對應的方法
  *
  * @param:通過方法傳入對象找到對應的傳遞參數映射
  *
  * @return:返回執行後的參數對象
  */
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  // 這裏通過方法名字以及參數通過解析對應的mapper來執行對應的操作
  System.out.println("在這裏執行實際方法");
  return null;
 }
 
}

3.2. Client

1
2
3
4
5
6
7
8
9
10
11
12
13
package javaproxy;
  
import java.lang.reflect.Proxy;
  
public class Client {
    
  public static void main(String[] args) {
    
  Dao dao=MapperProxy.newMapperProxy(Dao.class, null);
  dao.save();
  
 }
}

 3.3. 結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章