java中動態代理


一、在java中怎樣實現動態代理

 

1、我們要有一個接口,還要有一個接口的實現類,而這個實現類呢就是我們要代理的對象

接口:

1 package org.dynamicproxy.test;
2 
3 public interface UserDao {
4     public void addUser(User user);
5 }

接口的實現類(即要代理的對象):

 1 package org.dynamicproxy.test;
 2 
 3 public class UserDaoMysqlImpl implements UserDao {
 4 
 5     public void addUser(User user) {
 6         // TODO Auto-generated method stub
 7         System.out.println("connect to MySQL DataBase...");
 8         System.out.println("id為"+user.getId()+"的用戶信息成功添加到數據庫表中...");
 9     }
10 
11 }

順便說下,所謂代理呢也就是在調用實現類的方法時,可以在方法執行前后做額外的工作,這個就是代理。


2、我們要自己寫一個在要代理類的方法執行時,能夠做額外工作的類,而這個類必須繼承InvocationHandler接口

處理類(即能夠做額外工作的類):

 1 package org.dynamicproxy.test;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class LogHandler implements InvocationHandler {
 7     // 持有被代理對象的引用(此引用可以有外部靈活制定的)
 8     private Object target;
 9 
10     public LogHandler(Object target) {
11         this.target = target;
12     }
13 
14     public Object invoke(Object proxy, Method method, Object[] args)
15             throws Throwable {
16         // TODO Auto-generated method stub
17         System.out.println("開始記錄日志,添加用戶方法開始執行...");
18         method.invoke(target, args);
19         System.out.println("開始記錄日志,添加用戶方法執行結束...");
20         return null;
21     }
22 
23 }

順便說下為什么要繼承InvocationHandler接口呢?

因為代理類的實例在調用實現類的方法的時候,不會調真正的實現類的這個方法, 而是轉而調用這個類的invoke方法(繼承時必須實現的方法),在這個方法中你可以調用真正的實現類的這個方法。 

 

3、用代理類的實例去調用實現類的方法。

 1 package org.dynamicproxy.test;
 2 
 3 import java.lang.reflect.Proxy;
 4 
 5 import org.junit.Test;
 6 
 7 public class TestProxy{
 8  
 9     @Test
10     public void testProxy(){
11     UserDao userDAO = new UserDaoMysqlImpl();
12     LogHandler li = new LogHandler(userDAO);  //創建一個Handerler對象
13   
14     UserDao userDAOProxy = (UserDao)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
15     userDAOProxy.addUser(new User("001"));
16    
17 }
18 }

newProxyInstance參數含義
* 第一個參數:代理的類加載器,必須和被代理的對象是一個類加載器
* 第二個參數含義:代理對象要實現的那些接口
* 第三個參數:指派方法調用的調用處理程序

代理調用過程
* 得到UserDaoMysqlImpl這個類的一個代理類userDAOProxy,同時為代理類綁定了一個處理類LogHandler li
* 每次調用UserDaoMysqlImpl這個子類的addUser方法時,
* 不是userDAO這個UserDaoMysqlImpl類的實例去調用,
* 而是這個UserDaoMysqlImpl的代理類userDAOProxy去調用它自己的invoke方法,
* 這個invoke方法里呢可以調用userDAO這個實例的addUser方法

 

所以說要實現java的動態代理,InvocationHandler接口和Proxy是必須要用到的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM