這篇文章給大家介紹Java中代理的原理是什么,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
為烏翠等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及烏翠網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為網(wǎng)站制作、網(wǎng)站建設、烏翠網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
Java主要應用于:1. web開發(fā);2. Android開發(fā);3. 客戶端開發(fā);4. 網(wǎng)頁開發(fā);5. 企業(yè)級應用開發(fā);6. Java大數(shù)據(jù)開發(fā);7.游戲開發(fā)等。
1.什么是代理
動態(tài)代理技術是整個java技術中最重要的一個技術,它是學習java框架的基礎,不會動態(tài)代理技術,那么在學習Spring這些框架時是學不明白的。
動態(tài)代理技術就是用來產(chǎn)生一個對象的代理對象的。在開發(fā)中為什么需要為一個對象產(chǎn)生代理對象呢?
舉一個現(xiàn)實生活中的例子:歌星或者明星都有一個自己的經(jīng)紀人,這個經(jīng)紀人就是他們的代理人,當我們需要找明星表演時,不能直接找到該明星,只能是找明星的代理人。比如劉德華在現(xiàn)實生活中非常有名,會唱歌,會跳舞,會拍戲,劉德華在沒有出名之前,我們可以直接找他唱歌,跳舞,拍戲,劉德華出名之后,他干的第一件事就是找一個經(jīng)紀人,這個經(jīng)紀人就是劉德華的代理人(代理),當我們需要找劉德華表演時,不能直接找到劉德華了(劉德華說,你找我代理人商談具體事宜吧!),只能是找劉德華的代理人,因此劉德華這個代理人存在的價值就是攔截我們對劉德華的直接訪問!
這個現(xiàn)實中的例子和我們在開發(fā)中是一樣的,我們在開發(fā)中之所以要產(chǎn)生一個對象的代理對象,主要用于攔截對真實業(yè)務對象的訪問。那么代理對象應該具有什么方法呢?代理對象應該具有和目標對象相同的方法
所以在這里明確代理對象的兩個概念:
1、代理對象存在的價值主要用于攔截對真實業(yè)務對象的訪問。
2、代理對象應該具有和目標對象(真實業(yè)務對象)相同的方法。劉德華(真實業(yè)務對象)會唱歌,會跳舞,會拍戲,我們現(xiàn)在不能直接找他唱歌,跳舞,拍戲了,只能找他的代理人(代理對象)唱歌,跳舞,拍戲,一個人要想成為劉德華的代理人,那么他必須具有和劉德華一樣的行為(會唱歌,會跳舞,會拍戲),劉德華有什么方法,他(代理人)就要有什么方法,我們找劉德華的代理人唱歌,跳舞,拍戲,但是代理人不是真的懂得唱歌,跳舞,拍戲的,真正懂得唱歌,跳舞,拍戲的是劉德華,在現(xiàn)實中的例子就是我們要找劉德華唱歌,跳舞,拍戲,那么只能先找他的經(jīng)紀人,交錢給他的經(jīng)紀人,然后經(jīng)紀人再讓劉德華去唱歌,跳舞,拍戲。
靜態(tài)代理:代理類和委托類在代碼運行之前關系就已經(jīng)確定了,也就是說在代理類的代碼一開始就已經(jīng)存在了。
動態(tài)代理:動態(tài)代理類的字節(jié)碼在程序運行的時候生成。
現(xiàn)在要生成某一個對象的代理對象,這個代理對象通常也要編寫一個類來生成,所以首先要編寫用于生成代理對象的類。在java中如何用程序去生成一個對象的代理對象呢,java在JDK1.5之后提供了一個"java.lang.reflect.Proxy"類,通過"Proxy"類提供的一個newProxyInstance方法用來創(chuàng)建一個對象的代理對象,如下所示:
static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h)
newProxyInstance方法用來返回一個代理對象,這個方法總共有3個參數(shù),ClassLoader loader用來指明生成代理對象使用哪個類裝載器,Class>[] interfaces用來指明生成哪個對象的代理對象,通過接口指定,InvocationHandler h用來指明產(chǎn)生的這個代理對象要做什么事情。所以我們只需要調(diào)用newProxyInstance方法就可以得到某一個對象的代理對象了。
在java中規(guī)定,要想產(chǎn)生一個對象的代理對象,那么這個對象必須要有一個接口,所以我們第一步就是設計這個對象的接口,在接口中定義這個對象所具有的行為(方法)
StduentInterface.java--定義對象的行為接口
public interface StduentInterface { public int insertStudent(Student student); }
StudentDao.java--定義目標業(yè)務對象類
public class StudentDAO implements StduentInterface { @Override public int insertStudent(Student student) { // 以下這段代碼是業(yè)務邏輯 return null == student ? 0 : 1; } }
創(chuàng)建靜態(tài)代理
public class StudentStaticProxyDAO { private StudentDAO studentDAO; public StudentStaticProxyDAO(StudentDAO studentDAO) { this.studentDAO = studentDAO; } public int insertStudent(Student student) { Logger.info("開始插入一個學生記錄: " + student.toString()); int number = studentDAO.insertStudent(student); Logger.info("插入 " + number + " 條學生記錄"); return number; } }
動態(tài)代理
public class LoggerDynamicProxy implements InvocationHandler{ private Object target; public LoggerDynamicProxy(Object obj) { this.target = obj; } /** * 動態(tài)代理類中的 invoke 方法 * * 三個參數(shù)的意義: * * proxy :代理對象 * method : 委托類中要調(diào)用的方法 * args :method 方法的參數(shù) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Logger.info("before 業(yè)務方法調(diào)用之前"); Object obj = method.invoke(target, args); Logger.info("before 業(yè)務方法調(diào)用之前"); return obj; } }
測試類
public class ProxyTest { public static void main(String[] args) { /** * 基礎組件準備 */ StudentDAO studentDao = new StudentDAO(); Student student = new Student(100000); StudentStaticProxyDAO studentProxyDAO = new StudentStaticProxyDAO(studentDao); /** * 測試委托類的功能 */ System.out.println(studentDao.insertStudent(student)); /** * 測試靜態(tài)代理類的功能 */ System.out.println(studentProxyDAO.insertStudent(student)); /** * 測試動態(tài)代理類的功能 */ StduentInterface newProxyInstance = (StduentInterface)Proxy.newProxyInstance(studentDao.getClass().getClassLoader(), studentDao.getClass().getInterfaces(), new LoggerDynamicProxy(studentDao)); int insertStudent = newProxyInstance.insertStudent(student); System.out.println(insertStudent); }
運行結果
1
INFO: 開始插入一個學生記錄: Student [id=100000, name=null]
INFO: 插入 1 條學生記錄
1
INFO: before 業(yè)務方法調(diào)用之前
INFO: before 業(yè)務方法調(diào)用之前
1
INFO: before 業(yè)務方法調(diào)用之前
INFO: before 業(yè)務方法調(diào)用之前
1
關于Java中代理的原理是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。