黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國(guó)咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) 學(xué)習(xí)攻略 Java學(xué)習(xí) Java動(dòng)態(tài)代理原理

Java動(dòng)態(tài)代理原理

更新時(shí)間:2022-05-06 10:25:00 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1386次

動(dòng)力節(jié)點(diǎn)小編來(lái)告訴大家Java動(dòng)態(tài)代理原理是什么。Java動(dòng)態(tài)代理機(jī)制的出現(xiàn),給Java開發(fā)者帶來(lái)了不必手工編寫代理類,只需指定一組接口和委托類對(duì)象,就可以動(dòng)態(tài)獲取代理類。代理類負(fù)責(zé)將所有的方法調(diào)用分配給委托對(duì)象進(jìn)行反射執(zhí)行,在分派執(zhí)行的過(guò)程中,開發(fā)者還可以根據(jù)需要調(diào)整委托類對(duì)象及其功能,這是一個(gè)非常靈活靈活的代理框架。現(xiàn)在讓我們開始學(xué)習(xí)動(dòng)態(tài)代理。

動(dòng)態(tài)代理簡(jiǎn)述在java動(dòng)態(tài)代理機(jī)制中,有兩個(gè)重要的類或接口,一個(gè)是InvocationHandler(Interface)、另一個(gè)是Proxy(Class)。

InvocationHandler(interface)說(shuō)明:

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.
Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

每個(gè)動(dòng)態(tài)代理類都必須實(shí)現(xiàn) InvocationHandler 這個(gè)接口,并且代理類的每個(gè)實(shí)例都關(guān)聯(lián)一個(gè)處理程序,當(dāng)我們通過(guò)代理對(duì)象調(diào)用一種方式時(shí),對(duì)該方法的調(diào)用會(huì)轉(zhuǎn)發(fā)到 InvocationHandler 這個(gè)接口的 invoke 方法來(lái)進(jìn)行調(diào)用. 我們來(lái)看看 InvocationHandler 做這個(gè)接口的唯一方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

該方法接受三個(gè)參數(shù)并返回一個(gè) Object 類型,它們的含義如下:

proxy: 指我們所代表的真實(shí)對(duì)象 method: 指我們要調(diào)用真實(shí)對(duì)象的方法 Method object args: 指在真實(shí)對(duì)象上調(diào)用方法時(shí)接受的參數(shù) Back to Object真實(shí)對(duì)象方法的返回類型,以上內(nèi)容將在下面的例子中進(jìn)一步理解。

the value to return from the method invocation on the proxy instance.

Proxy(Class)說(shuō)明:

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.

Proxy 此類用于動(dòng)態(tài)創(chuàng)建代理對(duì)象。我們經(jīng)常使用 newProxyInstance 這個(gè)方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

參數(shù)理解:

// One ClassLoader object , Defined by which ClassLoader Object to load the generated proxy object 
loader - the class loader to define the proxy class 
// One Interface An array of objects , What is the set of interfaces that I'm going to provide to the object that I need to proxy 
interfaces - the list of interfaces for the proxy class to implement 
// One InvocationHandler object , Represents when my dynamic proxy object is calling a method , Which one does it relate to InvocationHandler On the object 
h - the invocation handler to dispatch method invocations to

返回結(jié)果的理解:代理對(duì)象的一個(gè)??實(shí)例

a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces

普通Java代理我們創(chuàng)建一個(gè)Java項(xiàng)目用于測(cè)試和理解動(dòng)態(tài)代理,項(xiàng)目結(jié)構(gòu)如下:

1.我們定義一個(gè)接口Interface,添加兩個(gè)方法。

package com.huhx.proxy;
public interface Interface {
void getMyName();
String getNameById(String id);
}

2.定義一個(gè)實(shí)現(xiàn)上述接口的真實(shí)類,RealObject:

package com.huhx.proxy;
public class RealObject implements Interface {
@Override
public void getMyName() {
System.out.println("my name is huhx");
}
@Override
public String getNameById(String id) {
System.out.println("argument id: " + id);
return "huhx";
}./* Welcome to join java communication Q Your appearance :909038429 Blow water and chat together
}

3.... 和 、 定義一個(gè)代理對(duì)象,它也實(shí)現(xiàn)了上面的接口接口:

package com.huhx.proxy;
public class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
@Override
public void getMyName() {
System.out.println("proxy getmyname");
proxied.getMyName();
}
@Override
public String getNameById(String id) {
System.out.println("proxy getnamebyid");
return proxied.getNameById(id);
}
}

4.SimpleMain在Main方法中,測(cè)試上述結(jié)果:

package com.huhx.proxy;
public class SimpleMain {
private static void consume(Interface iface) {
iface.getMyName();
String name = iface.getNameById("1");
System.out.println("name: " + name);
}
public static void main(String[] args) {
consume(new RealObject());
System.out.println("========================================================");
consume(new SimpleProxy(new RealObject()));
}
}

5.... 和 、 運(yùn)行結(jié)果如下:

my name is huhx
argument id: 1
name: huhx
========================================================
proxy getmyname
my name is huhx
proxy getnamebyid
argument id: 1
name: huhx

Java動(dòng)態(tài)代理完成了上面簡(jiǎn)單的Java代理,現(xiàn)在我們開始學(xué)習(xí)Java動(dòng)態(tài)代理,它比代理的思想更進(jìn)了一步,因?yàn)樗梢詣?dòng)態(tài)創(chuàng)建代理并動(dòng)態(tài)處理對(duì)代理方法的調(diào)用。在動(dòng)態(tài)代理上進(jìn)行的所有調(diào)用都被重定向到單個(gè)調(diào)用處理程序,它的工作是揭示調(diào)用的類型并確定相應(yīng)的對(duì)策。下面我們通過(guò)案例加深對(duì)Java動(dòng)態(tài)代理的理解:

1.創(chuàng)建一個(gè)繼承 InvocationHandler 的處理器:DynamicProxyHandler

package com.huhx.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
System.out.println("dynamic proxy handler constuctor: " + proxied.getClass());
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("dynamic proxy name: " + proxy.getClass());
System.out.println("method: " + method.getName());
System.out.println("args: " + Arrays.toString(args));
Object invokeObject = method.invoke(proxied, args);
if (invokeObject != null) {
System.out.println("invoke object: " + invokeObject.getClass());
} else {
System.out.println("invoke object is null");
}
return invokeObject;
}
}

2.我們寫一個(gè)測(cè)試Main方法,DynamicProxyMain:

package com.huhx.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.huhx.proxy.Interface;
import com.huhx.proxy.RealObject;
public class DynamicProxyMain {
public static void consumer(Interface iface) {
iface.getMyName();
String name = iface.getNameById("1");
System.out.println("name: " + name);
}
public static void main(String[] args) throws Exception, SecurityException, Throwable {
RealObject realObject = new RealObject();
consumer(realObject);
System.out.println("==============================");
// A dynamic proxy 
ClassLoader classLoader = Interface.class.getClassLoader();
Class<?>[] interfaces = new Class[] { Interface.class };
InvocationHandler handler = new DynamicProxyHandler(realObject);
Interface proxy = (Interface) Proxy.newProxyInstance(classLoader, interfaces, handler);
System.out.println("in dynamicproxyMain proxy: " + proxy.getClass());
consumer(proxy);
}./* Welcome to join java communication Q Your appearance :909038429 Blow water and chat together
}

3. ... 和 、 運(yùn)行結(jié)果如下:

my name is huhx
argument id: 1
name: huhx
==============================
dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
in dynamicproxyMain proxy: class com.sun.proxy.$Proxy0
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getNameById
args: [1]
argument id: 1
invoke object: class java.lang.String
name: huhx

從以上輸出,我們可以得出以下結(jié)論:

與代理對(duì)象InvocationHandler相關(guān)聯(lián),只有當(dāng)代理對(duì)象調(diào)用一個(gè)方法時(shí),才進(jìn)行invoke方法invoke 的三個(gè)參數(shù)的理解:對(duì)象代理是代理的對(duì)象,方法方法是真實(shí)對(duì)象調(diào)用的方法class , Object[] args 是真實(shí)對(duì)象中調(diào)用方法的參數(shù)

Java動(dòng)態(tài)代理的原理

1.動(dòng)態(tài)代理的關(guān)鍵代碼是Proxy.newProxyInstance(classLoader, interfaces, handler),我們跟進(jìn)源碼看看:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
// handler Can't be empty 
if (h == null) {
throw new NullPointerException();
}
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
// adopt loader And interface , Get a proxy Class object 
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
}
});
} else {
// Create an instance of the proxy object 
return newInstance(cons, ih);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}

2.我們來(lái)看newInstance方法的源碼:

private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString());
}
}
}

3....和、 當(dāng)我們通過(guò)代理對(duì)象調(diào)用一種方式時(shí),對(duì)該方法的調(diào)用轉(zhuǎn)發(fā) InvocationHandler 這個(gè)接口的 invoke 方法進(jìn)行調(diào)用。體現(xiàn)這句話的代碼,在源碼中沒有找到,所以在測(cè)試類的main方法中添加如下代碼:

if (proxy instanceof Proxy) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
invocationHandler.invoke(proxy, realObject.getClass().getMethod("getMyName"), null);
System.out.println("--------------------------------------");
}

這段代碼的輸出如下,而且,在上面,調(diào)用代理對(duì)象getMyName的方法輸出是一樣的,不知道!jvm 是否按此方式判斷到底:

dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null

通過(guò)上述介紹,相信大家對(duì)Java動(dòng)態(tài)代理原理已經(jīng)有所了解,大家如果想了解更多相關(guān)知識(shí),不妨來(lái)關(guān)注一下動(dòng)力節(jié)點(diǎn)的Java在線學(xué)習(xí),里面還有更豐富的知識(shí)等著大家去學(xué)習(xí),希望對(duì)大家能夠有所幫助哦。

提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)

  • 全國(guó)校區(qū) 2025-05-15 搶座中
  • 全國(guó)校區(qū) 2025-06-05 搶座中
  • 全國(guó)校區(qū) 2025-06-26 搶座中
免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 国产成人啪精品视频免费软件 | 在线观看理论片免费韩国 | 性欧美videos另类视频 | 一级毛片毛片毛片毛毛片 | 日日日日日| 天天草综合网 | 中文字幕精品亚洲无线码二区 | 一级全黄男女免费大片 | 天天爽天天爽天天片a久久网 | 亚洲伦理在线 | 色五月视频 | 成人午夜动漫在线观看 | 欧美日韩高清不卡免费观看 | 黄污视频在线 | 成人福利在线播放 | 久草看片| 干干干日日日 | 91短视频版在线观看免费大全 | 亚洲欧美天堂网 | 一级在线毛片 | 亚洲无线码一区在线观看 | 搜索毛片| a级精品国产片在线观看 | 国产精品福利在线观看秒播 | 性欧美成人免费观看视 | 亚洲综合日韩在线亚洲欧美专区 | 成人18xxxx网站| 亚洲天天做日日做天天看 | 国产免费理论片在线观看 | 亚洲日本中文字幕区 | 中国一级做a爱片免费 | 成人亚洲国产 | 国产一区视频在线 | 看片地址 | jizjizjizji在线观看 | 特级淫片日本高清视频 | 久久99网| 精品视频中文字幕 | 张柏芝国产一区在线观看 | 久久婷婷色 | 国产成人精品免费视频大全办公室 |